From 6d9c74238eefff31526336dddbffac9a7af017cb Mon Sep 17 00:00:00 2001 From: Vu Le Date: Fri, 6 Nov 2026 23:07:54 +0000 Subject: [PATCH 01/30] add global-scoped ExternalVolumeClass message in ateapi.proto, regenerate ateapi.go, and register ExternalVolumeClass in apitool TestBuild_Annotations. Signed-off-by: Vu Le --- api/ateapi/v1/ateapi.pb.go | 1359 +++++++++++--------- api/ateapi/v1/ateapi.proto | 34 + tools/apitool/internal/model/model_test.go | 17 +- 3 files changed, 770 insertions(+), 640 deletions(-) diff --git a/api/ateapi/v1/ateapi.pb.go b/api/ateapi/v1/ateapi.pb.go index d63c010fb1..a6a774b771 100644 --- a/api/ateapi/v1/ateapi.pb.go +++ b/api/ateapi/v1/ateapi.pb.go @@ -4047,6 +4047,87 @@ func (x *ExternalVolumeTemplate) GetStorageClassName() string { return "" } +// ExternalVolumeClass names the CSI driver that provisions external volumes +// and the parameters for its CreateVolume call. Global-scoped and immutable: +// metadata.atespace must be empty. +type ExternalVolumeClass 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"` + // driver_name is the CSI driver that provisions the volumes, e.g. + // "nfs.csi.k8s.io". It is a DNS subdomain, optionally prefixed with + // "substrate.io/". + // + // +k8s:required + // +k8s:maxLength=63 + // +k8s:customValidation # optional "substrate.io/" prefix + DNS-1123 subdomain + DriverName string `protobuf:"bytes,2,opt,name=driver_name,json=driverName,proto3" json:"driver_name,omitempty"` + // parameters are passed unchanged to the driver's CreateVolume call. The + // driver defines their keys and values, so they are only bounded in size. + // + // +k8s:optional + // +k8s:maxProperties=32 + // +k8s:eachKey=+k8s:maxLength=128 + // +k8s:eachVal=+k8s:maxLength=256 + Parameters map[string]string `protobuf:"bytes,3,rep,name=parameters,proto3" json:"parameters,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ExternalVolumeClass) Reset() { + *x = ExternalVolumeClass{} + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[44] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ExternalVolumeClass) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExternalVolumeClass) ProtoMessage() {} + +func (x *ExternalVolumeClass) ProtoReflect() protoreflect.Message { + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[44] + 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 ExternalVolumeClass.ProtoReflect.Descriptor instead. +func (*ExternalVolumeClass) Descriptor() ([]byte, []int) { + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{44} +} + +func (x *ExternalVolumeClass) GetMetadata() *ResourceMetadata { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *ExternalVolumeClass) GetDriverName() string { + if x != nil { + return x.DriverName + } + return "" +} + +func (x *ExternalVolumeClass) GetParameters() map[string]string { + if x != nil { + return x.Parameters + } + return nil +} + // SystemInfoVolumeSource is a read-only volume of substrate-generated // per-actor files (identity fields, projected trust bundles), regenerated by // atelet on every Run/Restore. @@ -4067,7 +4148,7 @@ type SystemInfoVolumeSource struct { func (x *SystemInfoVolumeSource) Reset() { *x = SystemInfoVolumeSource{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[44] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4079,7 +4160,7 @@ func (x *SystemInfoVolumeSource) String() string { func (*SystemInfoVolumeSource) ProtoMessage() {} func (x *SystemInfoVolumeSource) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[44] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4092,7 +4173,7 @@ func (x *SystemInfoVolumeSource) ProtoReflect() protoreflect.Message { // Deprecated: Use SystemInfoVolumeSource.ProtoReflect.Descriptor instead. func (*SystemInfoVolumeSource) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{44} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{45} } func (x *SystemInfoVolumeSource) GetDataSources() []*SystemInfoDataSource { @@ -4118,7 +4199,7 @@ type SystemInfoDataSource struct { func (x *SystemInfoDataSource) Reset() { *x = SystemInfoDataSource{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[45] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4130,7 +4211,7 @@ func (x *SystemInfoDataSource) String() string { func (*SystemInfoDataSource) ProtoMessage() {} func (x *SystemInfoDataSource) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[45] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4143,7 +4224,7 @@ func (x *SystemInfoDataSource) ProtoReflect() protoreflect.Message { // Deprecated: Use SystemInfoDataSource.ProtoReflect.Descriptor instead. func (*SystemInfoDataSource) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{45} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{46} } func (x *SystemInfoDataSource) GetActorMetadata() *ActorMetadataDataSource { @@ -4180,7 +4261,7 @@ type ActorMetadataDataSource struct { func (x *ActorMetadataDataSource) Reset() { *x = ActorMetadataDataSource{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[46] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4192,7 +4273,7 @@ func (x *ActorMetadataDataSource) String() string { func (*ActorMetadataDataSource) ProtoMessage() {} func (x *ActorMetadataDataSource) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[46] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4205,7 +4286,7 @@ func (x *ActorMetadataDataSource) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorMetadataDataSource.ProtoReflect.Descriptor instead. func (*ActorMetadataDataSource) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{46} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{47} } func (x *ActorMetadataDataSource) GetItems() []*ActorMetadataItem { @@ -4237,7 +4318,7 @@ type ActorMetadataItem struct { func (x *ActorMetadataItem) Reset() { *x = ActorMetadataItem{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[47] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4249,7 +4330,7 @@ func (x *ActorMetadataItem) String() string { func (*ActorMetadataItem) ProtoMessage() {} func (x *ActorMetadataItem) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[47] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4262,7 +4343,7 @@ func (x *ActorMetadataItem) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorMetadataItem.ProtoReflect.Descriptor instead. func (*ActorMetadataItem) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{47} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{48} } func (x *ActorMetadataItem) GetField() ActorMetadataField { @@ -4314,7 +4395,7 @@ type TrustBundleDataSource struct { func (x *TrustBundleDataSource) Reset() { *x = TrustBundleDataSource{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[48] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4326,7 +4407,7 @@ func (x *TrustBundleDataSource) String() string { func (*TrustBundleDataSource) ProtoMessage() {} func (x *TrustBundleDataSource) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[48] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4339,7 +4420,7 @@ func (x *TrustBundleDataSource) ProtoReflect() protoreflect.Message { // Deprecated: Use TrustBundleDataSource.ProtoReflect.Descriptor instead. func (*TrustBundleDataSource) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{48} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{49} } func (x *TrustBundleDataSource) GetNames() []string { @@ -4379,7 +4460,7 @@ type VolumeMount struct { func (x *VolumeMount) Reset() { *x = VolumeMount{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[49] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4391,7 +4472,7 @@ func (x *VolumeMount) String() string { func (*VolumeMount) ProtoMessage() {} func (x *VolumeMount) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[49] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4404,7 +4485,7 @@ func (x *VolumeMount) ProtoReflect() protoreflect.Message { // Deprecated: Use VolumeMount.ProtoReflect.Descriptor instead. func (*VolumeMount) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{49} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{50} } func (x *VolumeMount) GetName() string { @@ -4433,7 +4514,7 @@ type CreateAtespaceRequest struct { func (x *CreateAtespaceRequest) Reset() { *x = CreateAtespaceRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[50] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4445,7 +4526,7 @@ func (x *CreateAtespaceRequest) String() string { func (*CreateAtespaceRequest) ProtoMessage() {} func (x *CreateAtespaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[50] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4458,7 +4539,7 @@ func (x *CreateAtespaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateAtespaceRequest.ProtoReflect.Descriptor instead. func (*CreateAtespaceRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{50} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{51} } func (x *CreateAtespaceRequest) GetAtespace() *Atespace { @@ -4479,7 +4560,7 @@ type GetAtespaceRequest struct { func (x *GetAtespaceRequest) Reset() { *x = GetAtespaceRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[51] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4491,7 +4572,7 @@ func (x *GetAtespaceRequest) String() string { func (*GetAtespaceRequest) ProtoMessage() {} func (x *GetAtespaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[51] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[52] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4504,7 +4585,7 @@ func (x *GetAtespaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAtespaceRequest.ProtoReflect.Descriptor instead. func (*GetAtespaceRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{51} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{52} } func (x *GetAtespaceRequest) GetAtespace() *ObjectRef { @@ -4526,7 +4607,7 @@ type ListAtespacesRequest struct { func (x *ListAtespacesRequest) Reset() { *x = ListAtespacesRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[52] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4538,7 +4619,7 @@ func (x *ListAtespacesRequest) String() string { func (*ListAtespacesRequest) ProtoMessage() {} func (x *ListAtespacesRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[52] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[53] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4551,7 +4632,7 @@ func (x *ListAtespacesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListAtespacesRequest.ProtoReflect.Descriptor instead. func (*ListAtespacesRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{52} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{53} } func (x *ListAtespacesRequest) GetOptions() *ListOptions { @@ -4573,7 +4654,7 @@ type ListAtespacesResponse struct { func (x *ListAtespacesResponse) Reset() { *x = ListAtespacesResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[53] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4585,7 +4666,7 @@ func (x *ListAtespacesResponse) String() string { func (*ListAtespacesResponse) ProtoMessage() {} func (x *ListAtespacesResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[53] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[54] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4598,7 +4679,7 @@ func (x *ListAtespacesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListAtespacesResponse.ProtoReflect.Descriptor instead. func (*ListAtespacesResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{53} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{54} } func (x *ListAtespacesResponse) GetAtespaces() []*Atespace { @@ -4630,7 +4711,7 @@ type DeleteAtespaceRequest struct { func (x *DeleteAtespaceRequest) Reset() { *x = DeleteAtespaceRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[54] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4642,7 +4723,7 @@ func (x *DeleteAtespaceRequest) String() string { func (*DeleteAtespaceRequest) ProtoMessage() {} func (x *DeleteAtespaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[54] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[55] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4655,7 +4736,7 @@ func (x *DeleteAtespaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteAtespaceRequest.ProtoReflect.Descriptor instead. func (*DeleteAtespaceRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{54} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{55} } func (x *DeleteAtespaceRequest) GetAtespace() *ObjectRef { @@ -4686,7 +4767,7 @@ type CreateActorTemplateRequest struct { func (x *CreateActorTemplateRequest) Reset() { *x = CreateActorTemplateRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[55] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4698,7 +4779,7 @@ func (x *CreateActorTemplateRequest) String() string { func (*CreateActorTemplateRequest) ProtoMessage() {} func (x *CreateActorTemplateRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[55] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[56] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4711,7 +4792,7 @@ func (x *CreateActorTemplateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateActorTemplateRequest.ProtoReflect.Descriptor instead. func (*CreateActorTemplateRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{55} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{56} } func (x *CreateActorTemplateRequest) GetActorTemplate() *ActorTemplate { @@ -4732,7 +4813,7 @@ type GetActorTemplateRequest struct { func (x *GetActorTemplateRequest) Reset() { *x = GetActorTemplateRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[56] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4744,7 +4825,7 @@ func (x *GetActorTemplateRequest) String() string { func (*GetActorTemplateRequest) ProtoMessage() {} func (x *GetActorTemplateRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[56] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[57] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4757,7 +4838,7 @@ func (x *GetActorTemplateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetActorTemplateRequest.ProtoReflect.Descriptor instead. func (*GetActorTemplateRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{56} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{57} } func (x *GetActorTemplateRequest) GetActorTemplate() *ObjectRef { @@ -4785,7 +4866,7 @@ type ListActorTemplatesRequest struct { func (x *ListActorTemplatesRequest) Reset() { *x = ListActorTemplatesRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[57] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4797,7 +4878,7 @@ func (x *ListActorTemplatesRequest) String() string { func (*ListActorTemplatesRequest) ProtoMessage() {} func (x *ListActorTemplatesRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[57] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[58] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4810,7 +4891,7 @@ func (x *ListActorTemplatesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListActorTemplatesRequest.ProtoReflect.Descriptor instead. func (*ListActorTemplatesRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{57} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{58} } func (x *ListActorTemplatesRequest) GetAtespace() string { @@ -4840,7 +4921,7 @@ type ListActorTemplatesResponse struct { func (x *ListActorTemplatesResponse) Reset() { *x = ListActorTemplatesResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[58] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4852,7 +4933,7 @@ func (x *ListActorTemplatesResponse) String() string { func (*ListActorTemplatesResponse) ProtoMessage() {} func (x *ListActorTemplatesResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[58] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[59] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4865,7 +4946,7 @@ func (x *ListActorTemplatesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListActorTemplatesResponse.ProtoReflect.Descriptor instead. func (*ListActorTemplatesResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{58} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{59} } func (x *ListActorTemplatesResponse) GetActorTemplates() []*ActorTemplate { @@ -4897,7 +4978,7 @@ type DeleteActorTemplateRequest struct { func (x *DeleteActorTemplateRequest) Reset() { *x = DeleteActorTemplateRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[59] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4909,7 +4990,7 @@ func (x *DeleteActorTemplateRequest) String() string { func (*DeleteActorTemplateRequest) ProtoMessage() {} func (x *DeleteActorTemplateRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[59] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[60] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4922,7 +5003,7 @@ func (x *DeleteActorTemplateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteActorTemplateRequest.ProtoReflect.Descriptor instead. func (*DeleteActorTemplateRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{59} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{60} } func (x *DeleteActorTemplateRequest) GetActorTemplate() *ObjectRef { @@ -4950,7 +5031,7 @@ type GetActorRequest struct { func (x *GetActorRequest) Reset() { *x = GetActorRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[60] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4962,7 +5043,7 @@ func (x *GetActorRequest) String() string { func (*GetActorRequest) ProtoMessage() {} func (x *GetActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[60] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[61] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4975,7 +5056,7 @@ func (x *GetActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetActorRequest.ProtoReflect.Descriptor instead. func (*GetActorRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{60} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{61} } func (x *GetActorRequest) GetActor() *ObjectRef { @@ -4998,7 +5079,7 @@ type CreateActorRequest struct { func (x *CreateActorRequest) Reset() { *x = CreateActorRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[61] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5010,7 +5091,7 @@ func (x *CreateActorRequest) String() string { func (*CreateActorRequest) ProtoMessage() {} func (x *CreateActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[61] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[62] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5023,7 +5104,7 @@ func (x *CreateActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateActorRequest.ProtoReflect.Descriptor instead. func (*CreateActorRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{61} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{62} } func (x *CreateActorRequest) GetActor() *Actor { @@ -5054,7 +5135,7 @@ type UpdateActorRequest struct { func (x *UpdateActorRequest) Reset() { *x = UpdateActorRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[62] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5066,7 +5147,7 @@ func (x *UpdateActorRequest) String() string { func (*UpdateActorRequest) ProtoMessage() {} func (x *UpdateActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[62] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[63] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5079,7 +5160,7 @@ func (x *UpdateActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateActorRequest.ProtoReflect.Descriptor instead. func (*UpdateActorRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{62} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{63} } func (x *UpdateActorRequest) GetActor() *Actor { @@ -5104,7 +5185,7 @@ type SuspendActorRequest struct { func (x *SuspendActorRequest) Reset() { *x = SuspendActorRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[63] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5116,7 +5197,7 @@ func (x *SuspendActorRequest) String() string { func (*SuspendActorRequest) ProtoMessage() {} func (x *SuspendActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[63] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[64] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5129,7 +5210,7 @@ func (x *SuspendActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SuspendActorRequest.ProtoReflect.Descriptor instead. func (*SuspendActorRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{63} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{64} } func (x *SuspendActorRequest) GetActor() *ObjectRef { @@ -5155,7 +5236,7 @@ type SuspendActorResponse struct { func (x *SuspendActorResponse) Reset() { *x = SuspendActorResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[64] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5167,7 +5248,7 @@ func (x *SuspendActorResponse) String() string { func (*SuspendActorResponse) ProtoMessage() {} func (x *SuspendActorResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[64] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[65] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5180,7 +5261,7 @@ func (x *SuspendActorResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SuspendActorResponse.ProtoReflect.Descriptor instead. func (*SuspendActorResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{64} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{65} } func (x *SuspendActorResponse) GetActor() *Actor { @@ -5206,7 +5287,7 @@ type SuspendOptions struct { func (x *SuspendOptions) Reset() { *x = SuspendOptions{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[65] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5218,7 +5299,7 @@ func (x *SuspendOptions) String() string { func (*SuspendOptions) ProtoMessage() {} func (x *SuspendOptions) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[65] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[66] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5231,7 +5312,7 @@ func (x *SuspendOptions) ProtoReflect() protoreflect.Message { // Deprecated: Use SuspendOptions.ProtoReflect.Descriptor instead. func (*SuspendOptions) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{65} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{66} } func (x *SuspendOptions) GetMode() DurabilityMode { @@ -5252,7 +5333,7 @@ type ResumeActorRequest struct { func (x *ResumeActorRequest) Reset() { *x = ResumeActorRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[66] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5264,7 +5345,7 @@ func (x *ResumeActorRequest) String() string { func (*ResumeActorRequest) ProtoMessage() {} func (x *ResumeActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[66] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[67] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5277,7 +5358,7 @@ func (x *ResumeActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ResumeActorRequest.ProtoReflect.Descriptor instead. func (*ResumeActorRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{66} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{67} } func (x *ResumeActorRequest) GetActor() *ObjectRef { @@ -5299,7 +5380,7 @@ type ResumeActorResponse struct { func (x *ResumeActorResponse) Reset() { *x = ResumeActorResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[67] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5311,7 +5392,7 @@ func (x *ResumeActorResponse) String() string { func (*ResumeActorResponse) ProtoMessage() {} func (x *ResumeActorResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[67] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[68] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5324,7 +5405,7 @@ func (x *ResumeActorResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ResumeActorResponse.ProtoReflect.Descriptor instead. func (*ResumeActorResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{67} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{68} } func (x *ResumeActorResponse) GetActor() *Actor { @@ -5354,7 +5435,7 @@ type RevertActorRequest struct { func (x *RevertActorRequest) Reset() { *x = RevertActorRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[68] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5366,7 +5447,7 @@ func (x *RevertActorRequest) String() string { func (*RevertActorRequest) ProtoMessage() {} func (x *RevertActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[68] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[69] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5379,7 +5460,7 @@ func (x *RevertActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RevertActorRequest.ProtoReflect.Descriptor instead. func (*RevertActorRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{68} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{69} } func (x *RevertActorRequest) GetActor() *ObjectRef { @@ -5401,7 +5482,7 @@ type RevertActorResponse struct { func (x *RevertActorResponse) Reset() { *x = RevertActorResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[69] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5413,7 +5494,7 @@ func (x *RevertActorResponse) String() string { func (*RevertActorResponse) ProtoMessage() {} func (x *RevertActorResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[69] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[70] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5426,7 +5507,7 @@ func (x *RevertActorResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RevertActorResponse.ProtoReflect.Descriptor instead. func (*RevertActorResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{69} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{70} } func (x *RevertActorResponse) GetActor() *Actor { @@ -5451,7 +5532,7 @@ type DeleteActorRequest struct { func (x *DeleteActorRequest) Reset() { *x = DeleteActorRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[70] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5463,7 +5544,7 @@ func (x *DeleteActorRequest) String() string { func (*DeleteActorRequest) ProtoMessage() {} func (x *DeleteActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[70] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[71] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5476,7 +5557,7 @@ func (x *DeleteActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteActorRequest.ProtoReflect.Descriptor instead. func (*DeleteActorRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{70} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{71} } func (x *DeleteActorRequest) GetActor() *ObjectRef { @@ -5513,7 +5594,7 @@ type GetActorEgressPolicyRequest struct { func (x *GetActorEgressPolicyRequest) Reset() { *x = GetActorEgressPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[71] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5525,7 +5606,7 @@ func (x *GetActorEgressPolicyRequest) String() string { func (*GetActorEgressPolicyRequest) ProtoMessage() {} func (x *GetActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[71] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[72] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5538,7 +5619,7 @@ func (x *GetActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetActorEgressPolicyRequest.ProtoReflect.Descriptor instead. func (*GetActorEgressPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{71} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{72} } func (x *GetActorEgressPolicyRequest) GetActor() *ObjectRef { @@ -5576,7 +5657,7 @@ type CreateActorEgressPolicyRequest struct { func (x *CreateActorEgressPolicyRequest) Reset() { *x = CreateActorEgressPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[72] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5588,7 +5669,7 @@ func (x *CreateActorEgressPolicyRequest) String() string { func (*CreateActorEgressPolicyRequest) ProtoMessage() {} func (x *CreateActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[72] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[73] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5601,7 +5682,7 @@ func (x *CreateActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateActorEgressPolicyRequest.ProtoReflect.Descriptor instead. func (*CreateActorEgressPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{72} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{73} } func (x *CreateActorEgressPolicyRequest) GetActor() *ObjectRef { @@ -5639,7 +5720,7 @@ type UpdateActorEgressPolicyRequest struct { func (x *UpdateActorEgressPolicyRequest) Reset() { *x = UpdateActorEgressPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[73] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5651,7 +5732,7 @@ func (x *UpdateActorEgressPolicyRequest) String() string { func (*UpdateActorEgressPolicyRequest) ProtoMessage() {} func (x *UpdateActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[73] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[74] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5664,7 +5745,7 @@ func (x *UpdateActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateActorEgressPolicyRequest.ProtoReflect.Descriptor instead. func (*UpdateActorEgressPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{73} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{74} } func (x *UpdateActorEgressPolicyRequest) GetActor() *ObjectRef { @@ -5705,7 +5786,7 @@ type DeleteActorEgressPolicyRequest struct { func (x *DeleteActorEgressPolicyRequest) Reset() { *x = DeleteActorEgressPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[74] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5717,7 +5798,7 @@ func (x *DeleteActorEgressPolicyRequest) String() string { func (*DeleteActorEgressPolicyRequest) ProtoMessage() {} func (x *DeleteActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[74] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[75] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5730,7 +5811,7 @@ func (x *DeleteActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteActorEgressPolicyRequest.ProtoReflect.Descriptor instead. func (*DeleteActorEgressPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{74} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{75} } func (x *DeleteActorEgressPolicyRequest) GetActor() *ObjectRef { @@ -5765,7 +5846,7 @@ type GetTagRequest struct { func (x *GetTagRequest) Reset() { *x = GetTagRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[75] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5777,7 +5858,7 @@ func (x *GetTagRequest) String() string { func (*GetTagRequest) ProtoMessage() {} func (x *GetTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[75] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[76] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5790,7 +5871,7 @@ func (x *GetTagRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetTagRequest.ProtoReflect.Descriptor instead. func (*GetTagRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{75} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{76} } func (x *GetTagRequest) GetTag() *ObjectRef { @@ -5829,7 +5910,7 @@ type MintActorJwtRequest struct { func (x *MintActorJwtRequest) Reset() { *x = MintActorJwtRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[76] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5841,7 +5922,7 @@ func (x *MintActorJwtRequest) String() string { func (*MintActorJwtRequest) ProtoMessage() {} func (x *MintActorJwtRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[76] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[77] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5854,7 +5935,7 @@ func (x *MintActorJwtRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MintActorJwtRequest.ProtoReflect.Descriptor instead. func (*MintActorJwtRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{76} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{77} } func (x *MintActorJwtRequest) GetActor() *ObjectRef { @@ -5909,7 +5990,7 @@ type MintActorJwtResponse struct { func (x *MintActorJwtResponse) Reset() { *x = MintActorJwtResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[77] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5921,7 +6002,7 @@ func (x *MintActorJwtResponse) String() string { func (*MintActorJwtResponse) ProtoMessage() {} func (x *MintActorJwtResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[77] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[78] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5934,7 +6015,7 @@ func (x *MintActorJwtResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MintActorJwtResponse.ProtoReflect.Descriptor instead. func (*MintActorJwtResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{77} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{78} } func (x *MintActorJwtResponse) GetActorJwt() string { @@ -5968,7 +6049,7 @@ type ListTagsRequest struct { func (x *ListTagsRequest) Reset() { *x = ListTagsRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[78] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5980,7 +6061,7 @@ func (x *ListTagsRequest) String() string { func (*ListTagsRequest) ProtoMessage() {} func (x *ListTagsRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[78] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[79] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5993,7 +6074,7 @@ func (x *ListTagsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListTagsRequest.ProtoReflect.Descriptor instead. func (*ListTagsRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{78} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{79} } func (x *ListTagsRequest) GetAtespace() string { @@ -6020,7 +6101,7 @@ type ListTagsResponse struct { func (x *ListTagsResponse) Reset() { *x = ListTagsResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[79] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6032,7 +6113,7 @@ func (x *ListTagsResponse) String() string { func (*ListTagsResponse) ProtoMessage() {} func (x *ListTagsResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[79] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[80] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6045,7 +6126,7 @@ func (x *ListTagsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListTagsResponse.ProtoReflect.Descriptor instead. func (*ListTagsResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{79} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{80} } func (x *ListTagsResponse) GetTags() []*Tag { @@ -6090,7 +6171,7 @@ type CreateTagRequest struct { func (x *CreateTagRequest) Reset() { *x = CreateTagRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[80] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6102,7 +6183,7 @@ func (x *CreateTagRequest) String() string { func (*CreateTagRequest) ProtoMessage() {} func (x *CreateTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[80] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[81] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6115,7 +6196,7 @@ func (x *CreateTagRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateTagRequest.ProtoReflect.Descriptor instead. func (*CreateTagRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{80} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{81} } func (x *CreateTagRequest) GetTag() *Tag { @@ -6145,7 +6226,7 @@ type UpdateTagRequest struct { func (x *UpdateTagRequest) Reset() { *x = UpdateTagRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[81] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6157,7 +6238,7 @@ func (x *UpdateTagRequest) String() string { func (*UpdateTagRequest) ProtoMessage() {} func (x *UpdateTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[81] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[82] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6170,7 +6251,7 @@ func (x *UpdateTagRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateTagRequest.ProtoReflect.Descriptor instead. func (*UpdateTagRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{81} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{82} } func (x *UpdateTagRequest) GetTag() *Tag { @@ -6195,7 +6276,7 @@ type DeleteTagRequest struct { func (x *DeleteTagRequest) Reset() { *x = DeleteTagRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[82] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6207,7 +6288,7 @@ func (x *DeleteTagRequest) String() string { func (*DeleteTagRequest) ProtoMessage() {} func (x *DeleteTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[82] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[83] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6220,7 +6301,7 @@ func (x *DeleteTagRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteTagRequest.ProtoReflect.Descriptor instead. func (*DeleteTagRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{82} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{83} } func (x *DeleteTagRequest) GetTag() *ObjectRef { @@ -6259,7 +6340,7 @@ type DeleteOptions struct { func (x *DeleteOptions) Reset() { *x = DeleteOptions{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[83] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[84] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6271,7 +6352,7 @@ func (x *DeleteOptions) String() string { func (*DeleteOptions) ProtoMessage() {} func (x *DeleteOptions) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[83] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[84] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6284,7 +6365,7 @@ func (x *DeleteOptions) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteOptions.ProtoReflect.Descriptor instead. func (*DeleteOptions) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{83} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{84} } func (x *DeleteOptions) GetVersion() int64 { @@ -6323,7 +6404,7 @@ type ListOptions struct { func (x *ListOptions) Reset() { *x = ListOptions{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[84] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[85] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6335,7 +6416,7 @@ func (x *ListOptions) String() string { func (*ListOptions) ProtoMessage() {} func (x *ListOptions) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[84] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[85] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6348,7 +6429,7 @@ func (x *ListOptions) ProtoReflect() protoreflect.Message { // Deprecated: Use ListOptions.ProtoReflect.Descriptor instead. func (*ListOptions) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{84} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{85} } func (x *ListOptions) GetPageSize() int32 { @@ -6384,7 +6465,7 @@ type ListWorkerActorAssignmentsRequest struct { func (x *ListWorkerActorAssignmentsRequest) Reset() { *x = ListWorkerActorAssignmentsRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[85] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[86] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6396,7 +6477,7 @@ func (x *ListWorkerActorAssignmentsRequest) String() string { func (*ListWorkerActorAssignmentsRequest) ProtoMessage() {} func (x *ListWorkerActorAssignmentsRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[85] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[86] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6409,7 +6490,7 @@ func (x *ListWorkerActorAssignmentsRequest) ProtoReflect() protoreflect.Message // Deprecated: Use ListWorkerActorAssignmentsRequest.ProtoReflect.Descriptor instead. func (*ListWorkerActorAssignmentsRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{85} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{86} } func (x *ListWorkerActorAssignmentsRequest) GetWorker() *ObjectRef { @@ -6439,7 +6520,7 @@ type ListWorkerActorAssignmentsResponse struct { func (x *ListWorkerActorAssignmentsResponse) Reset() { *x = ListWorkerActorAssignmentsResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[86] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[87] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6451,7 +6532,7 @@ func (x *ListWorkerActorAssignmentsResponse) String() string { func (*ListWorkerActorAssignmentsResponse) ProtoMessage() {} func (x *ListWorkerActorAssignmentsResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[86] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[87] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6464,7 +6545,7 @@ func (x *ListWorkerActorAssignmentsResponse) ProtoReflect() protoreflect.Message // Deprecated: Use ListWorkerActorAssignmentsResponse.ProtoReflect.Descriptor instead. func (*ListWorkerActorAssignmentsResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{86} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{87} } func (x *ListWorkerActorAssignmentsResponse) GetActorAssignments() []*ActorAssignment { @@ -6493,7 +6574,7 @@ type ListWorkersRequest struct { func (x *ListWorkersRequest) Reset() { *x = ListWorkersRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[87] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[88] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6505,7 +6586,7 @@ func (x *ListWorkersRequest) String() string { func (*ListWorkersRequest) ProtoMessage() {} func (x *ListWorkersRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[87] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[88] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6518,7 +6599,7 @@ func (x *ListWorkersRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkersRequest.ProtoReflect.Descriptor instead. func (*ListWorkersRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{87} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{88} } func (x *ListWorkersRequest) GetOptions() *ListOptions { @@ -6540,7 +6621,7 @@ type ListWorkersResponse struct { func (x *ListWorkersResponse) Reset() { *x = ListWorkersResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[88] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[89] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6552,7 +6633,7 @@ func (x *ListWorkersResponse) String() string { func (*ListWorkersResponse) ProtoMessage() {} func (x *ListWorkersResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[88] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[89] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6565,7 +6646,7 @@ func (x *ListWorkersResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkersResponse.ProtoReflect.Descriptor instead. func (*ListWorkersResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{88} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{89} } func (x *ListWorkersResponse) GetWorkers() []*Worker { @@ -6595,7 +6676,7 @@ type GetWorkerRequest struct { func (x *GetWorkerRequest) Reset() { *x = GetWorkerRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[89] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[90] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6607,7 +6688,7 @@ func (x *GetWorkerRequest) String() string { func (*GetWorkerRequest) ProtoMessage() {} func (x *GetWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[89] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[90] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6620,7 +6701,7 @@ func (x *GetWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetWorkerRequest.ProtoReflect.Descriptor instead. func (*GetWorkerRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{89} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{90} } func (x *GetWorkerRequest) GetWorker() *ObjectRef { @@ -6642,7 +6723,7 @@ type CreateWorkerRequest struct { func (x *CreateWorkerRequest) Reset() { *x = CreateWorkerRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[90] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[91] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6654,7 +6735,7 @@ func (x *CreateWorkerRequest) String() string { func (*CreateWorkerRequest) ProtoMessage() {} func (x *CreateWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[90] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[91] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6667,7 +6748,7 @@ func (x *CreateWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateWorkerRequest.ProtoReflect.Descriptor instead. func (*CreateWorkerRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{90} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{91} } func (x *CreateWorkerRequest) GetWorker() *Worker { @@ -6702,7 +6783,7 @@ type UpdateWorkerRequest struct { func (x *UpdateWorkerRequest) Reset() { *x = UpdateWorkerRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[91] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[92] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6714,7 +6795,7 @@ func (x *UpdateWorkerRequest) String() string { func (*UpdateWorkerRequest) ProtoMessage() {} func (x *UpdateWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[91] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[92] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6727,7 +6808,7 @@ func (x *UpdateWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateWorkerRequest.ProtoReflect.Descriptor instead. func (*UpdateWorkerRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{91} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{92} } func (x *UpdateWorkerRequest) GetWorker() *Worker { @@ -6754,7 +6835,7 @@ type DeleteWorkerRequest struct { func (x *DeleteWorkerRequest) Reset() { *x = DeleteWorkerRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[92] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[93] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6766,7 +6847,7 @@ func (x *DeleteWorkerRequest) String() string { func (*DeleteWorkerRequest) ProtoMessage() {} func (x *DeleteWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[92] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[93] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6779,7 +6860,7 @@ func (x *DeleteWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteWorkerRequest.ProtoReflect.Descriptor instead. func (*DeleteWorkerRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{92} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{93} } func (x *DeleteWorkerRequest) GetWorker() *ObjectRef { @@ -6809,7 +6890,7 @@ type DrainWorkerRequest struct { func (x *DrainWorkerRequest) Reset() { *x = DrainWorkerRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[93] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[94] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6821,7 +6902,7 @@ func (x *DrainWorkerRequest) String() string { func (*DrainWorkerRequest) ProtoMessage() {} func (x *DrainWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[93] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[94] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6834,7 +6915,7 @@ func (x *DrainWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DrainWorkerRequest.ProtoReflect.Descriptor instead. func (*DrainWorkerRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{93} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{94} } func (x *DrainWorkerRequest) GetWorker() *ObjectRef { @@ -6855,7 +6936,7 @@ type DrainWorkerResponse struct { func (x *DrainWorkerResponse) Reset() { *x = DrainWorkerResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[94] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[95] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6867,7 +6948,7 @@ func (x *DrainWorkerResponse) String() string { func (*DrainWorkerResponse) ProtoMessage() {} func (x *DrainWorkerResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[94] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[95] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6880,7 +6961,7 @@ func (x *DrainWorkerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DrainWorkerResponse.ProtoReflect.Descriptor instead. func (*DrainWorkerResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{94} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{95} } func (x *DrainWorkerResponse) GetWorker() *Worker { @@ -6904,7 +6985,7 @@ type MarkWorkerAvailableRequest struct { func (x *MarkWorkerAvailableRequest) Reset() { *x = MarkWorkerAvailableRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[95] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[96] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6916,7 +6997,7 @@ func (x *MarkWorkerAvailableRequest) String() string { func (*MarkWorkerAvailableRequest) ProtoMessage() {} func (x *MarkWorkerAvailableRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[95] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[96] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6929,7 +7010,7 @@ func (x *MarkWorkerAvailableRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MarkWorkerAvailableRequest.ProtoReflect.Descriptor instead. func (*MarkWorkerAvailableRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{95} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{96} } func (x *MarkWorkerAvailableRequest) GetWorker() *ObjectRef { @@ -6950,7 +7031,7 @@ type MarkWorkerAvailableResponse struct { func (x *MarkWorkerAvailableResponse) Reset() { *x = MarkWorkerAvailableResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[96] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[97] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6962,7 +7043,7 @@ func (x *MarkWorkerAvailableResponse) String() string { func (*MarkWorkerAvailableResponse) ProtoMessage() {} func (x *MarkWorkerAvailableResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[96] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[97] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6975,7 +7056,7 @@ func (x *MarkWorkerAvailableResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MarkWorkerAvailableResponse.ProtoReflect.Descriptor instead. func (*MarkWorkerAvailableResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{96} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{97} } func (x *MarkWorkerAvailableResponse) GetWorker() *Worker { @@ -6999,7 +7080,7 @@ type MarkWorkerUnavailableRequest struct { func (x *MarkWorkerUnavailableRequest) Reset() { *x = MarkWorkerUnavailableRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[97] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[98] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7011,7 +7092,7 @@ func (x *MarkWorkerUnavailableRequest) String() string { func (*MarkWorkerUnavailableRequest) ProtoMessage() {} func (x *MarkWorkerUnavailableRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[97] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[98] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7024,7 +7105,7 @@ func (x *MarkWorkerUnavailableRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MarkWorkerUnavailableRequest.ProtoReflect.Descriptor instead. func (*MarkWorkerUnavailableRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{97} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{98} } func (x *MarkWorkerUnavailableRequest) GetWorker() *ObjectRef { @@ -7045,7 +7126,7 @@ type MarkWorkerUnavailableResponse struct { func (x *MarkWorkerUnavailableResponse) Reset() { *x = MarkWorkerUnavailableResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[98] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[99] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7057,7 +7138,7 @@ func (x *MarkWorkerUnavailableResponse) String() string { func (*MarkWorkerUnavailableResponse) ProtoMessage() {} func (x *MarkWorkerUnavailableResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[98] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[99] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7070,7 +7151,7 @@ func (x *MarkWorkerUnavailableResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MarkWorkerUnavailableResponse.ProtoReflect.Descriptor instead. func (*MarkWorkerUnavailableResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{98} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{99} } func (x *MarkWorkerUnavailableResponse) GetWorker() *Worker { @@ -7099,7 +7180,7 @@ type ListActorsRequest struct { func (x *ListActorsRequest) Reset() { *x = ListActorsRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[99] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[100] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7111,7 +7192,7 @@ func (x *ListActorsRequest) String() string { func (*ListActorsRequest) ProtoMessage() {} func (x *ListActorsRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[99] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[100] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7124,7 +7205,7 @@ func (x *ListActorsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListActorsRequest.ProtoReflect.Descriptor instead. func (*ListActorsRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{99} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{100} } func (x *ListActorsRequest) GetAtespace() string { @@ -7153,7 +7234,7 @@ type ListActorsResponse struct { func (x *ListActorsResponse) Reset() { *x = ListActorsResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[100] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[101] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7165,7 +7246,7 @@ func (x *ListActorsResponse) String() string { func (*ListActorsResponse) ProtoMessage() {} func (x *ListActorsResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[100] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[101] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7178,7 +7259,7 @@ func (x *ListActorsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListActorsResponse.ProtoReflect.Descriptor instead. func (*ListActorsResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{100} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{101} } func (x *ListActorsResponse) GetActors() []*Actor { @@ -7266,7 +7347,7 @@ type Worker struct { func (x *Worker) Reset() { *x = Worker{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[101] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[102] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7278,7 +7359,7 @@ func (x *Worker) String() string { func (*Worker) ProtoMessage() {} func (x *Worker) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[101] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[102] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7291,7 +7372,7 @@ func (x *Worker) ProtoReflect() protoreflect.Message { // Deprecated: Use Worker.ProtoReflect.Descriptor instead. func (*Worker) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{101} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{102} } func (x *Worker) GetMetadata() *ResourceMetadata { @@ -7433,7 +7514,7 @@ type WorkerStatus struct { func (x *WorkerStatus) Reset() { *x = WorkerStatus{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[102] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[103] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7445,7 +7526,7 @@ func (x *WorkerStatus) String() string { func (*WorkerStatus) ProtoMessage() {} func (x *WorkerStatus) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[102] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[103] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7458,7 +7539,7 @@ func (x *WorkerStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkerStatus.ProtoReflect.Descriptor instead. func (*WorkerStatus) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{102} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{103} } func (x *WorkerStatus) GetState() WorkerState { @@ -7546,7 +7627,7 @@ type WorkerSandboxClass struct { func (x *WorkerSandboxClass) Reset() { *x = WorkerSandboxClass{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[103] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[104] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7558,7 +7639,7 @@ func (x *WorkerSandboxClass) String() string { func (*WorkerSandboxClass) ProtoMessage() {} func (x *WorkerSandboxClass) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[103] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[104] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7571,7 +7652,7 @@ func (x *WorkerSandboxClass) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkerSandboxClass.ProtoReflect.Descriptor instead. func (*WorkerSandboxClass) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{103} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{104} } func (x *WorkerSandboxClass) GetSandboxClass() string { @@ -7623,7 +7704,7 @@ type WorkerSandboxRuntime struct { func (x *WorkerSandboxRuntime) Reset() { *x = WorkerSandboxRuntime{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[104] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[105] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7635,7 +7716,7 @@ func (x *WorkerSandboxRuntime) String() string { func (*WorkerSandboxRuntime) ProtoMessage() {} func (x *WorkerSandboxRuntime) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[104] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[105] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7648,7 +7729,7 @@ func (x *WorkerSandboxRuntime) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkerSandboxRuntime.ProtoReflect.Descriptor instead. func (*WorkerSandboxRuntime) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{104} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{105} } func (x *WorkerSandboxRuntime) GetVersion() *VersionedSandboxCompat { @@ -7689,7 +7770,7 @@ type RuntimeOverhead struct { func (x *RuntimeOverhead) Reset() { *x = RuntimeOverhead{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[105] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[106] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7701,7 +7782,7 @@ func (x *RuntimeOverhead) String() string { func (*RuntimeOverhead) ProtoMessage() {} func (x *RuntimeOverhead) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[105] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[106] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7714,7 +7795,7 @@ func (x *RuntimeOverhead) ProtoReflect() protoreflect.Message { // Deprecated: Use RuntimeOverhead.ProtoReflect.Descriptor instead. func (*RuntimeOverhead) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{105} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{106} } func (x *RuntimeOverhead) GetMemoryBytes() int64 { @@ -7753,7 +7834,7 @@ type ActorSandboxRuntime struct { func (x *ActorSandboxRuntime) Reset() { *x = ActorSandboxRuntime{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[106] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[107] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7765,7 +7846,7 @@ func (x *ActorSandboxRuntime) String() string { func (*ActorSandboxRuntime) ProtoMessage() {} func (x *ActorSandboxRuntime) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[106] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[107] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7778,7 +7859,7 @@ func (x *ActorSandboxRuntime) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorSandboxRuntime.ProtoReflect.Descriptor instead. func (*ActorSandboxRuntime) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{106} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{107} } func (x *ActorSandboxRuntime) GetSandboxClass() string { @@ -7829,7 +7910,7 @@ type VersionedSandboxCompat struct { func (x *VersionedSandboxCompat) Reset() { *x = VersionedSandboxCompat{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[107] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[108] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7841,7 +7922,7 @@ func (x *VersionedSandboxCompat) String() string { func (*VersionedSandboxCompat) ProtoMessage() {} func (x *VersionedSandboxCompat) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[107] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[108] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7854,7 +7935,7 @@ func (x *VersionedSandboxCompat) ProtoReflect() protoreflect.Message { // Deprecated: Use VersionedSandboxCompat.ProtoReflect.Descriptor instead. func (*VersionedSandboxCompat) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{107} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{108} } func (x *VersionedSandboxCompat) GetSchemaVersion() string { @@ -7890,7 +7971,7 @@ type AttributeEntry struct { func (x *AttributeEntry) Reset() { *x = AttributeEntry{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[108] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[109] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7902,7 +7983,7 @@ func (x *AttributeEntry) String() string { func (*AttributeEntry) ProtoMessage() {} func (x *AttributeEntry) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[108] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[109] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7915,7 +7996,7 @@ func (x *AttributeEntry) ProtoReflect() protoreflect.Message { // Deprecated: Use AttributeEntry.ProtoReflect.Descriptor instead. func (*AttributeEntry) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{108} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{109} } func (x *AttributeEntry) GetKey() string { @@ -7962,7 +8043,7 @@ type WorkerResources struct { func (x *WorkerResources) Reset() { *x = WorkerResources{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[109] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[110] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7974,7 +8055,7 @@ func (x *WorkerResources) String() string { func (*WorkerResources) ProtoMessage() {} func (x *WorkerResources) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[109] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[110] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7987,7 +8068,7 @@ func (x *WorkerResources) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkerResources.ProtoReflect.Descriptor instead. func (*WorkerResources) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{109} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{110} } func (x *WorkerResources) GetCpuMillicores() int64 { @@ -8043,7 +8124,7 @@ type ActorAssignment struct { func (x *ActorAssignment) Reset() { *x = ActorAssignment{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[110] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[111] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8055,7 +8136,7 @@ func (x *ActorAssignment) String() string { func (*ActorAssignment) ProtoMessage() {} func (x *ActorAssignment) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[110] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[111] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8068,7 +8149,7 @@ func (x *ActorAssignment) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorAssignment.ProtoReflect.Descriptor instead. func (*ActorAssignment) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{110} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{111} } func (x *ActorAssignment) GetMetadata() *ResourceMetadata { @@ -8113,7 +8194,7 @@ type AcquireWorkerEpochRequest struct { func (x *AcquireWorkerEpochRequest) Reset() { *x = AcquireWorkerEpochRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[111] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[112] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8125,7 +8206,7 @@ func (x *AcquireWorkerEpochRequest) String() string { func (*AcquireWorkerEpochRequest) ProtoMessage() {} func (x *AcquireWorkerEpochRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[111] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[112] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8138,7 +8219,7 @@ func (x *AcquireWorkerEpochRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AcquireWorkerEpochRequest.ProtoReflect.Descriptor instead. func (*AcquireWorkerEpochRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{111} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{112} } func (x *AcquireWorkerEpochRequest) GetWorker() *ObjectRef { @@ -8158,7 +8239,7 @@ type AcquireWorkerEpochResponse struct { func (x *AcquireWorkerEpochResponse) Reset() { *x = AcquireWorkerEpochResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[112] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[113] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8170,7 +8251,7 @@ func (x *AcquireWorkerEpochResponse) String() string { func (*AcquireWorkerEpochResponse) ProtoMessage() {} func (x *AcquireWorkerEpochResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[112] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[113] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8183,7 +8264,7 @@ func (x *AcquireWorkerEpochResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AcquireWorkerEpochResponse.ProtoReflect.Descriptor instead. func (*AcquireWorkerEpochResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{112} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{113} } func (x *AcquireWorkerEpochResponse) GetEpoch() int64 { @@ -8226,7 +8307,7 @@ type RegisterWorkerRequest struct { func (x *RegisterWorkerRequest) Reset() { *x = RegisterWorkerRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[113] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[114] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8238,7 +8319,7 @@ func (x *RegisterWorkerRequest) String() string { func (*RegisterWorkerRequest) ProtoMessage() {} func (x *RegisterWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[113] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[114] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8251,7 +8332,7 @@ func (x *RegisterWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RegisterWorkerRequest.ProtoReflect.Descriptor instead. func (*RegisterWorkerRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{113} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{114} } func (x *RegisterWorkerRequest) GetWorker() *ObjectRef { @@ -8292,7 +8373,7 @@ type RegisterWorkerResponse struct { func (x *RegisterWorkerResponse) Reset() { *x = RegisterWorkerResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[114] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[115] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8304,7 +8385,7 @@ func (x *RegisterWorkerResponse) String() string { func (*RegisterWorkerResponse) ProtoMessage() {} func (x *RegisterWorkerResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[114] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[115] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8317,7 +8398,7 @@ func (x *RegisterWorkerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RegisterWorkerResponse.ProtoReflect.Descriptor instead. func (*RegisterWorkerResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{114} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{115} } func (x *RegisterWorkerResponse) GetWorker() *Worker { @@ -8357,7 +8438,7 @@ type SetWorkerSandboxRuntimesRequest struct { func (x *SetWorkerSandboxRuntimesRequest) Reset() { *x = SetWorkerSandboxRuntimesRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[115] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[116] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8369,7 +8450,7 @@ func (x *SetWorkerSandboxRuntimesRequest) String() string { func (*SetWorkerSandboxRuntimesRequest) ProtoMessage() {} func (x *SetWorkerSandboxRuntimesRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[115] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[116] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8382,7 +8463,7 @@ func (x *SetWorkerSandboxRuntimesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SetWorkerSandboxRuntimesRequest.ProtoReflect.Descriptor instead. func (*SetWorkerSandboxRuntimesRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{115} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{116} } func (x *SetWorkerSandboxRuntimesRequest) GetWorker() *ObjectRef { @@ -8416,7 +8497,7 @@ type SetWorkerSandboxRuntimesResponse struct { func (x *SetWorkerSandboxRuntimesResponse) Reset() { *x = SetWorkerSandboxRuntimesResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[116] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[117] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8428,7 +8509,7 @@ func (x *SetWorkerSandboxRuntimesResponse) String() string { func (*SetWorkerSandboxRuntimesResponse) ProtoMessage() {} func (x *SetWorkerSandboxRuntimesResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[116] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[117] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8441,7 +8522,7 @@ func (x *SetWorkerSandboxRuntimesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SetWorkerSandboxRuntimesResponse.ProtoReflect.Descriptor instead. func (*SetWorkerSandboxRuntimesResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{116} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{117} } func (x *SetWorkerSandboxRuntimesResponse) GetWorker() *Worker { @@ -8488,7 +8569,7 @@ type MintWorkerActorCertificateRequest struct { func (x *MintWorkerActorCertificateRequest) Reset() { *x = MintWorkerActorCertificateRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[117] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[118] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8500,7 +8581,7 @@ func (x *MintWorkerActorCertificateRequest) String() string { func (*MintWorkerActorCertificateRequest) ProtoMessage() {} func (x *MintWorkerActorCertificateRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[117] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[118] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8513,7 +8594,7 @@ func (x *MintWorkerActorCertificateRequest) ProtoReflect() protoreflect.Message // Deprecated: Use MintWorkerActorCertificateRequest.ProtoReflect.Descriptor instead. func (*MintWorkerActorCertificateRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{117} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{118} } func (x *MintWorkerActorCertificateRequest) GetActor() *ObjectRef { @@ -8557,7 +8638,7 @@ type MintWorkerActorCertificateResponse struct { func (x *MintWorkerActorCertificateResponse) Reset() { *x = MintWorkerActorCertificateResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[118] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[119] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8569,7 +8650,7 @@ func (x *MintWorkerActorCertificateResponse) String() string { func (*MintWorkerActorCertificateResponse) ProtoMessage() {} func (x *MintWorkerActorCertificateResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[118] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[119] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8582,7 +8663,7 @@ func (x *MintWorkerActorCertificateResponse) ProtoReflect() protoreflect.Message // Deprecated: Use MintWorkerActorCertificateResponse.ProtoReflect.Descriptor instead. func (*MintWorkerActorCertificateResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{118} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{119} } func (x *MintWorkerActorCertificateResponse) GetActorCertificates() [][]byte { @@ -8623,7 +8704,7 @@ type MintWorkerActorJwtRequest struct { func (x *MintWorkerActorJwtRequest) Reset() { *x = MintWorkerActorJwtRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[119] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[120] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8635,7 +8716,7 @@ func (x *MintWorkerActorJwtRequest) String() string { func (*MintWorkerActorJwtRequest) ProtoMessage() {} func (x *MintWorkerActorJwtRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[119] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[120] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8648,7 +8729,7 @@ func (x *MintWorkerActorJwtRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MintWorkerActorJwtRequest.ProtoReflect.Descriptor instead. func (*MintWorkerActorJwtRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{119} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{120} } func (x *MintWorkerActorJwtRequest) GetActor() *ObjectRef { @@ -8696,7 +8777,7 @@ type MintWorkerActorJwtResponse struct { func (x *MintWorkerActorJwtResponse) Reset() { *x = MintWorkerActorJwtResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[120] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[121] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8708,7 +8789,7 @@ func (x *MintWorkerActorJwtResponse) String() string { func (*MintWorkerActorJwtResponse) ProtoMessage() {} func (x *MintWorkerActorJwtResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[120] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[121] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8721,7 +8802,7 @@ func (x *MintWorkerActorJwtResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MintWorkerActorJwtResponse.ProtoReflect.Descriptor instead. func (*MintWorkerActorJwtResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{120} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{121} } func (x *MintWorkerActorJwtResponse) GetActorJwt() string { @@ -8772,7 +8853,7 @@ type RequestActorSuspendRequest struct { func (x *RequestActorSuspendRequest) Reset() { *x = RequestActorSuspendRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[121] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[122] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8784,7 +8865,7 @@ func (x *RequestActorSuspendRequest) String() string { func (*RequestActorSuspendRequest) ProtoMessage() {} func (x *RequestActorSuspendRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[121] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[122] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8797,7 +8878,7 @@ func (x *RequestActorSuspendRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RequestActorSuspendRequest.ProtoReflect.Descriptor instead. func (*RequestActorSuspendRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{121} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{122} } func (x *RequestActorSuspendRequest) GetWorker() *ObjectRef { @@ -8831,7 +8912,7 @@ type RequestActorSuspendResponse struct { func (x *RequestActorSuspendResponse) Reset() { *x = RequestActorSuspendResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[122] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[123] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8843,7 +8924,7 @@ func (x *RequestActorSuspendResponse) String() string { func (*RequestActorSuspendResponse) ProtoMessage() {} func (x *RequestActorSuspendResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[122] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[123] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8856,7 +8937,7 @@ func (x *RequestActorSuspendResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RequestActorSuspendResponse.ProtoReflect.Descriptor instead. func (*RequestActorSuspendResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{122} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{123} } func (x *RequestActorSuspendResponse) GetActor() *Actor { @@ -8896,7 +8977,7 @@ type ReportActorCrashedRequest struct { func (x *ReportActorCrashedRequest) Reset() { *x = ReportActorCrashedRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[123] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[124] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8908,7 +8989,7 @@ func (x *ReportActorCrashedRequest) String() string { func (*ReportActorCrashedRequest) ProtoMessage() {} func (x *ReportActorCrashedRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[123] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[124] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8921,7 +9002,7 @@ func (x *ReportActorCrashedRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportActorCrashedRequest.ProtoReflect.Descriptor instead. func (*ReportActorCrashedRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{123} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{124} } func (x *ReportActorCrashedRequest) GetWorker() *ObjectRef { @@ -8962,7 +9043,7 @@ type ReportActorCrashedResponse struct { func (x *ReportActorCrashedResponse) Reset() { *x = ReportActorCrashedResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[124] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[125] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8974,7 +9055,7 @@ func (x *ReportActorCrashedResponse) String() string { func (*ReportActorCrashedResponse) ProtoMessage() {} func (x *ReportActorCrashedResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[124] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[125] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8987,7 +9068,7 @@ func (x *ReportActorCrashedResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportActorCrashedResponse.ProtoReflect.Descriptor instead. func (*ReportActorCrashedResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{124} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{125} } func (x *ReportActorCrashedResponse) GetActor() *Actor { @@ -9018,7 +9099,7 @@ type ReportActorSnapshotStateRequest struct { func (x *ReportActorSnapshotStateRequest) Reset() { *x = ReportActorSnapshotStateRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[125] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[126] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9030,7 +9111,7 @@ func (x *ReportActorSnapshotStateRequest) String() string { func (*ReportActorSnapshotStateRequest) ProtoMessage() {} func (x *ReportActorSnapshotStateRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[125] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[126] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9043,7 +9124,7 @@ func (x *ReportActorSnapshotStateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportActorSnapshotStateRequest.ProtoReflect.Descriptor instead. func (*ReportActorSnapshotStateRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{125} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{126} } func (x *ReportActorSnapshotStateRequest) GetActor() *ObjectRef { @@ -9075,7 +9156,7 @@ type ReportActorSnapshotStateResponse struct { func (x *ReportActorSnapshotStateResponse) Reset() { *x = ReportActorSnapshotStateResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[126] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[127] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9087,7 +9168,7 @@ func (x *ReportActorSnapshotStateResponse) String() string { func (*ReportActorSnapshotStateResponse) ProtoMessage() {} func (x *ReportActorSnapshotStateResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[126] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[127] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9100,7 +9181,7 @@ func (x *ReportActorSnapshotStateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportActorSnapshotStateResponse.ProtoReflect.Descriptor instead. func (*ReportActorSnapshotStateResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{126} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{127} } // ActorSnapshotState is what atelet holds for one Actor on its node. It @@ -9134,7 +9215,7 @@ type ActorSnapshotState struct { func (x *ActorSnapshotState) Reset() { *x = ActorSnapshotState{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[127] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[128] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9146,7 +9227,7 @@ func (x *ActorSnapshotState) String() string { func (*ActorSnapshotState) ProtoMessage() {} func (x *ActorSnapshotState) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[127] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[128] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9159,7 +9240,7 @@ func (x *ActorSnapshotState) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorSnapshotState.ProtoReflect.Descriptor instead. func (*ActorSnapshotState) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{127} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{128} } func (x *ActorSnapshotState) GetLatestLocal() *SnapshotReport { @@ -9231,7 +9312,7 @@ type SnapshotReport struct { func (x *SnapshotReport) Reset() { *x = SnapshotReport{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[128] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[129] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9243,7 +9324,7 @@ func (x *SnapshotReport) String() string { func (*SnapshotReport) ProtoMessage() {} func (x *SnapshotReport) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[128] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[129] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9256,7 +9337,7 @@ func (x *SnapshotReport) ProtoReflect() protoreflect.Message { // Deprecated: Use SnapshotReport.ProtoReflect.Descriptor instead. func (*SnapshotReport) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{128} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{129} } func (x *SnapshotReport) GetUuid() string { @@ -9326,7 +9407,7 @@ type AccessPolicy struct { func (x *AccessPolicy) Reset() { *x = AccessPolicy{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[129] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[130] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9338,7 +9419,7 @@ func (x *AccessPolicy) String() string { func (*AccessPolicy) ProtoMessage() {} func (x *AccessPolicy) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[129] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[130] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9351,7 +9432,7 @@ func (x *AccessPolicy) ProtoReflect() protoreflect.Message { // Deprecated: Use AccessPolicy.ProtoReflect.Descriptor instead. func (*AccessPolicy) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{129} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{130} } func (x *AccessPolicy) GetMetadata() *ResourceMetadata { @@ -9393,7 +9474,7 @@ type Binding struct { func (x *Binding) Reset() { *x = Binding{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[130] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[131] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9405,7 +9486,7 @@ func (x *Binding) String() string { func (*Binding) ProtoMessage() {} func (x *Binding) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[130] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[131] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9418,7 +9499,7 @@ func (x *Binding) ProtoReflect() protoreflect.Message { // Deprecated: Use Binding.ProtoReflect.Descriptor instead. func (*Binding) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{130} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{131} } func (x *Binding) GetRole() string { @@ -9450,7 +9531,7 @@ type GetGlobalAccessPolicyRequest struct { func (x *GetGlobalAccessPolicyRequest) Reset() { *x = GetGlobalAccessPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[131] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[132] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9462,7 +9543,7 @@ func (x *GetGlobalAccessPolicyRequest) String() string { func (*GetGlobalAccessPolicyRequest) ProtoMessage() {} func (x *GetGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[131] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[132] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9475,7 +9556,7 @@ func (x *GetGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetGlobalAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*GetGlobalAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{131} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{132} } func (x *GetGlobalAccessPolicyRequest) GetName() string { @@ -9499,7 +9580,7 @@ type CreateGlobalAccessPolicyRequest struct { func (x *CreateGlobalAccessPolicyRequest) Reset() { *x = CreateGlobalAccessPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[132] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[133] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9511,7 +9592,7 @@ func (x *CreateGlobalAccessPolicyRequest) String() string { func (*CreateGlobalAccessPolicyRequest) ProtoMessage() {} func (x *CreateGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[132] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[133] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9524,7 +9605,7 @@ func (x *CreateGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateGlobalAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*CreateGlobalAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{132} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{133} } func (x *CreateGlobalAccessPolicyRequest) GetAccessPolicy() *AccessPolicy { @@ -9548,7 +9629,7 @@ type UpdateGlobalAccessPolicyRequest struct { func (x *UpdateGlobalAccessPolicyRequest) Reset() { *x = UpdateGlobalAccessPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[133] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[134] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9560,7 +9641,7 @@ func (x *UpdateGlobalAccessPolicyRequest) String() string { func (*UpdateGlobalAccessPolicyRequest) ProtoMessage() {} func (x *UpdateGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[133] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[134] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9573,7 +9654,7 @@ func (x *UpdateGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateGlobalAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*UpdateGlobalAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{133} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{134} } func (x *UpdateGlobalAccessPolicyRequest) GetAccessPolicy() *AccessPolicy { @@ -9603,7 +9684,7 @@ type GetAtespaceAccessPolicyRequest struct { func (x *GetAtespaceAccessPolicyRequest) Reset() { *x = GetAtespaceAccessPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[134] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[135] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9615,7 +9696,7 @@ func (x *GetAtespaceAccessPolicyRequest) String() string { func (*GetAtespaceAccessPolicyRequest) ProtoMessage() {} func (x *GetAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[134] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[135] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9628,7 +9709,7 @@ func (x *GetAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAtespaceAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*GetAtespaceAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{134} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{135} } func (x *GetAtespaceAccessPolicyRequest) GetAtespace() *ObjectRef { @@ -9664,7 +9745,7 @@ type CreateAtespaceAccessPolicyRequest struct { func (x *CreateAtespaceAccessPolicyRequest) Reset() { *x = CreateAtespaceAccessPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[135] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[136] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9676,7 +9757,7 @@ func (x *CreateAtespaceAccessPolicyRequest) String() string { func (*CreateAtespaceAccessPolicyRequest) ProtoMessage() {} func (x *CreateAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[135] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[136] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9689,7 +9770,7 @@ func (x *CreateAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message // Deprecated: Use CreateAtespaceAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*CreateAtespaceAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{135} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{136} } func (x *CreateAtespaceAccessPolicyRequest) GetAtespace() *ObjectRef { @@ -9725,7 +9806,7 @@ type UpdateAtespaceAccessPolicyRequest struct { func (x *UpdateAtespaceAccessPolicyRequest) Reset() { *x = UpdateAtespaceAccessPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[136] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[137] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9737,7 +9818,7 @@ func (x *UpdateAtespaceAccessPolicyRequest) String() string { func (*UpdateAtespaceAccessPolicyRequest) ProtoMessage() {} func (x *UpdateAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[136] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[137] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9750,7 +9831,7 @@ func (x *UpdateAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message // Deprecated: Use UpdateAtespaceAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*UpdateAtespaceAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{136} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{137} } func (x *UpdateAtespaceAccessPolicyRequest) GetAtespace() *ObjectRef { @@ -9791,7 +9872,7 @@ type DeleteAtespaceAccessPolicyRequest struct { func (x *DeleteAtespaceAccessPolicyRequest) Reset() { *x = DeleteAtespaceAccessPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[137] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[138] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9803,7 +9884,7 @@ func (x *DeleteAtespaceAccessPolicyRequest) String() string { func (*DeleteAtespaceAccessPolicyRequest) ProtoMessage() {} func (x *DeleteAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[137] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[138] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9816,7 +9897,7 @@ func (x *DeleteAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message // Deprecated: Use DeleteAtespaceAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*DeleteAtespaceAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{137} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{138} } func (x *DeleteAtespaceAccessPolicyRequest) GetAtespace() *ObjectRef { @@ -9862,7 +9943,7 @@ type ResourceAnnotation struct { func (x *ResourceAnnotation) Reset() { *x = ResourceAnnotation{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[138] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[139] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9874,7 +9955,7 @@ func (x *ResourceAnnotation) String() string { func (*ResourceAnnotation) ProtoMessage() {} func (x *ResourceAnnotation) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[138] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[139] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9887,7 +9968,7 @@ func (x *ResourceAnnotation) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceAnnotation.ProtoReflect.Descriptor instead. func (*ResourceAnnotation) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{138} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{139} } func (x *ResourceAnnotation) GetParents() []string { @@ -9930,7 +10011,7 @@ type MethodAnnotation struct { func (x *MethodAnnotation) Reset() { *x = MethodAnnotation{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[139] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[140] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9942,7 +10023,7 @@ func (x *MethodAnnotation) String() string { func (*MethodAnnotation) ProtoMessage() {} func (x *MethodAnnotation) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[139] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[140] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9955,7 +10036,7 @@ func (x *MethodAnnotation) ProtoReflect() protoreflect.Message { // Deprecated: Use MethodAnnotation.ProtoReflect.Descriptor instead. func (*MethodAnnotation) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{139} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{140} } func (x *MethodAnnotation) GetResource() string { @@ -10197,7 +10278,17 @@ const file_api_ateapi_v1_ateapi_proto_rawDesc = "" + "\x16DurableDirVolumeSource\"m\n" + "\x16ExternalVolumeTemplate\x12%\n" + "\x0ecapacity_bytes\x18\x01 \x01(\x03R\rcapacityBytes\x12,\n" + - "\x12storage_class_name\x18\x02 \x01(\tR\x10storageClassName\"f\n" + + "\x12storage_class_name\x18\x02 \x01(\tR\x10storageClassName\"\xb1\x02\n" + + "\x13ExternalVolumeClass\x12A\n" + + "\bmetadata\x18\x01 \x01(\v2%.substrate.ateapi.v1.ResourceMetadataR\bmetadata\x12\x1f\n" + + "\vdriver_name\x18\x02 \x01(\tR\n" + + "driverName\x12X\n" + + "\n" + + "parameters\x18\x03 \x03(\v28.substrate.ateapi.v1.ExternalVolumeClass.ParametersEntryR\n" + + "parameters\x1a=\n" + + "\x0fParametersEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01:\x1d\x82\xb5\x18\x19\x18\x02\"\x15ExternalVolumeClasses\"f\n" + "\x16SystemInfoVolumeSource\x12L\n" + "\fdata_sources\x18\x01 \x03(\v2).substrate.ateapi.v1.SystemInfoDataSourceR\vdataSources\"\xba\x01\n" + "\x14SystemInfoDataSource\x12S\n" + @@ -10663,7 +10754,7 @@ func file_api_ateapi_v1_ateapi_proto_rawDescGZIP() []byte { } var file_api_ateapi_v1_ateapi_proto_enumTypes = make([]protoimpl.EnumInfo, 10) -var file_api_ateapi_v1_ateapi_proto_msgTypes = make([]protoimpl.MessageInfo, 143) +var file_api_ateapi_v1_ateapi_proto_msgTypes = make([]protoimpl.MessageInfo, 145) var file_api_ateapi_v1_ateapi_proto_goTypes = []any{ (SnapshotOwner)(0), // 0: substrate.ateapi.v1.SnapshotOwner (SnapshotStorageState)(0), // 1: substrate.ateapi.v1.SnapshotStorageState @@ -10719,108 +10810,110 @@ var file_api_ateapi_v1_ateapi_proto_goTypes = []any{ (*ImageVolumeSource)(nil), // 51: substrate.ateapi.v1.ImageVolumeSource (*DurableDirVolumeSource)(nil), // 52: substrate.ateapi.v1.DurableDirVolumeSource (*ExternalVolumeTemplate)(nil), // 53: substrate.ateapi.v1.ExternalVolumeTemplate - (*SystemInfoVolumeSource)(nil), // 54: substrate.ateapi.v1.SystemInfoVolumeSource - (*SystemInfoDataSource)(nil), // 55: substrate.ateapi.v1.SystemInfoDataSource - (*ActorMetadataDataSource)(nil), // 56: substrate.ateapi.v1.ActorMetadataDataSource - (*ActorMetadataItem)(nil), // 57: substrate.ateapi.v1.ActorMetadataItem - (*TrustBundleDataSource)(nil), // 58: substrate.ateapi.v1.TrustBundleDataSource - (*VolumeMount)(nil), // 59: substrate.ateapi.v1.VolumeMount - (*CreateAtespaceRequest)(nil), // 60: substrate.ateapi.v1.CreateAtespaceRequest - (*GetAtespaceRequest)(nil), // 61: substrate.ateapi.v1.GetAtespaceRequest - (*ListAtespacesRequest)(nil), // 62: substrate.ateapi.v1.ListAtespacesRequest - (*ListAtespacesResponse)(nil), // 63: substrate.ateapi.v1.ListAtespacesResponse - (*DeleteAtespaceRequest)(nil), // 64: substrate.ateapi.v1.DeleteAtespaceRequest - (*CreateActorTemplateRequest)(nil), // 65: substrate.ateapi.v1.CreateActorTemplateRequest - (*GetActorTemplateRequest)(nil), // 66: substrate.ateapi.v1.GetActorTemplateRequest - (*ListActorTemplatesRequest)(nil), // 67: substrate.ateapi.v1.ListActorTemplatesRequest - (*ListActorTemplatesResponse)(nil), // 68: substrate.ateapi.v1.ListActorTemplatesResponse - (*DeleteActorTemplateRequest)(nil), // 69: substrate.ateapi.v1.DeleteActorTemplateRequest - (*GetActorRequest)(nil), // 70: substrate.ateapi.v1.GetActorRequest - (*CreateActorRequest)(nil), // 71: substrate.ateapi.v1.CreateActorRequest - (*UpdateActorRequest)(nil), // 72: substrate.ateapi.v1.UpdateActorRequest - (*SuspendActorRequest)(nil), // 73: substrate.ateapi.v1.SuspendActorRequest - (*SuspendActorResponse)(nil), // 74: substrate.ateapi.v1.SuspendActorResponse - (*SuspendOptions)(nil), // 75: substrate.ateapi.v1.SuspendOptions - (*ResumeActorRequest)(nil), // 76: substrate.ateapi.v1.ResumeActorRequest - (*ResumeActorResponse)(nil), // 77: substrate.ateapi.v1.ResumeActorResponse - (*RevertActorRequest)(nil), // 78: substrate.ateapi.v1.RevertActorRequest - (*RevertActorResponse)(nil), // 79: substrate.ateapi.v1.RevertActorResponse - (*DeleteActorRequest)(nil), // 80: substrate.ateapi.v1.DeleteActorRequest - (*GetActorEgressPolicyRequest)(nil), // 81: substrate.ateapi.v1.GetActorEgressPolicyRequest - (*CreateActorEgressPolicyRequest)(nil), // 82: substrate.ateapi.v1.CreateActorEgressPolicyRequest - (*UpdateActorEgressPolicyRequest)(nil), // 83: substrate.ateapi.v1.UpdateActorEgressPolicyRequest - (*DeleteActorEgressPolicyRequest)(nil), // 84: substrate.ateapi.v1.DeleteActorEgressPolicyRequest - (*GetTagRequest)(nil), // 85: substrate.ateapi.v1.GetTagRequest - (*MintActorJwtRequest)(nil), // 86: substrate.ateapi.v1.MintActorJwtRequest - (*MintActorJwtResponse)(nil), // 87: substrate.ateapi.v1.MintActorJwtResponse - (*ListTagsRequest)(nil), // 88: substrate.ateapi.v1.ListTagsRequest - (*ListTagsResponse)(nil), // 89: substrate.ateapi.v1.ListTagsResponse - (*CreateTagRequest)(nil), // 90: substrate.ateapi.v1.CreateTagRequest - (*UpdateTagRequest)(nil), // 91: substrate.ateapi.v1.UpdateTagRequest - (*DeleteTagRequest)(nil), // 92: substrate.ateapi.v1.DeleteTagRequest - (*DeleteOptions)(nil), // 93: substrate.ateapi.v1.DeleteOptions - (*ListOptions)(nil), // 94: substrate.ateapi.v1.ListOptions - (*ListWorkerActorAssignmentsRequest)(nil), // 95: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest - (*ListWorkerActorAssignmentsResponse)(nil), // 96: substrate.ateapi.v1.ListWorkerActorAssignmentsResponse - (*ListWorkersRequest)(nil), // 97: substrate.ateapi.v1.ListWorkersRequest - (*ListWorkersResponse)(nil), // 98: substrate.ateapi.v1.ListWorkersResponse - (*GetWorkerRequest)(nil), // 99: substrate.ateapi.v1.GetWorkerRequest - (*CreateWorkerRequest)(nil), // 100: substrate.ateapi.v1.CreateWorkerRequest - (*UpdateWorkerRequest)(nil), // 101: substrate.ateapi.v1.UpdateWorkerRequest - (*DeleteWorkerRequest)(nil), // 102: substrate.ateapi.v1.DeleteWorkerRequest - (*DrainWorkerRequest)(nil), // 103: substrate.ateapi.v1.DrainWorkerRequest - (*DrainWorkerResponse)(nil), // 104: substrate.ateapi.v1.DrainWorkerResponse - (*MarkWorkerAvailableRequest)(nil), // 105: substrate.ateapi.v1.MarkWorkerAvailableRequest - (*MarkWorkerAvailableResponse)(nil), // 106: substrate.ateapi.v1.MarkWorkerAvailableResponse - (*MarkWorkerUnavailableRequest)(nil), // 107: substrate.ateapi.v1.MarkWorkerUnavailableRequest - (*MarkWorkerUnavailableResponse)(nil), // 108: substrate.ateapi.v1.MarkWorkerUnavailableResponse - (*ListActorsRequest)(nil), // 109: substrate.ateapi.v1.ListActorsRequest - (*ListActorsResponse)(nil), // 110: substrate.ateapi.v1.ListActorsResponse - (*Worker)(nil), // 111: substrate.ateapi.v1.Worker - (*WorkerStatus)(nil), // 112: substrate.ateapi.v1.WorkerStatus - (*WorkerSandboxClass)(nil), // 113: substrate.ateapi.v1.WorkerSandboxClass - (*WorkerSandboxRuntime)(nil), // 114: substrate.ateapi.v1.WorkerSandboxRuntime - (*RuntimeOverhead)(nil), // 115: substrate.ateapi.v1.RuntimeOverhead - (*ActorSandboxRuntime)(nil), // 116: substrate.ateapi.v1.ActorSandboxRuntime - (*VersionedSandboxCompat)(nil), // 117: substrate.ateapi.v1.VersionedSandboxCompat - (*AttributeEntry)(nil), // 118: substrate.ateapi.v1.AttributeEntry - (*WorkerResources)(nil), // 119: substrate.ateapi.v1.WorkerResources - (*ActorAssignment)(nil), // 120: substrate.ateapi.v1.ActorAssignment - (*AcquireWorkerEpochRequest)(nil), // 121: substrate.ateapi.v1.AcquireWorkerEpochRequest - (*AcquireWorkerEpochResponse)(nil), // 122: substrate.ateapi.v1.AcquireWorkerEpochResponse - (*RegisterWorkerRequest)(nil), // 123: substrate.ateapi.v1.RegisterWorkerRequest - (*RegisterWorkerResponse)(nil), // 124: substrate.ateapi.v1.RegisterWorkerResponse - (*SetWorkerSandboxRuntimesRequest)(nil), // 125: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest - (*SetWorkerSandboxRuntimesResponse)(nil), // 126: substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse - (*MintWorkerActorCertificateRequest)(nil), // 127: substrate.ateapi.v1.MintWorkerActorCertificateRequest - (*MintWorkerActorCertificateResponse)(nil), // 128: substrate.ateapi.v1.MintWorkerActorCertificateResponse - (*MintWorkerActorJwtRequest)(nil), // 129: substrate.ateapi.v1.MintWorkerActorJwtRequest - (*MintWorkerActorJwtResponse)(nil), // 130: substrate.ateapi.v1.MintWorkerActorJwtResponse - (*RequestActorSuspendRequest)(nil), // 131: substrate.ateapi.v1.RequestActorSuspendRequest - (*RequestActorSuspendResponse)(nil), // 132: substrate.ateapi.v1.RequestActorSuspendResponse - (*ReportActorCrashedRequest)(nil), // 133: substrate.ateapi.v1.ReportActorCrashedRequest - (*ReportActorCrashedResponse)(nil), // 134: substrate.ateapi.v1.ReportActorCrashedResponse - (*ReportActorSnapshotStateRequest)(nil), // 135: substrate.ateapi.v1.ReportActorSnapshotStateRequest - (*ReportActorSnapshotStateResponse)(nil), // 136: substrate.ateapi.v1.ReportActorSnapshotStateResponse - (*ActorSnapshotState)(nil), // 137: substrate.ateapi.v1.ActorSnapshotState - (*SnapshotReport)(nil), // 138: substrate.ateapi.v1.SnapshotReport - (*AccessPolicy)(nil), // 139: substrate.ateapi.v1.AccessPolicy - (*Binding)(nil), // 140: substrate.ateapi.v1.Binding - (*GetGlobalAccessPolicyRequest)(nil), // 141: substrate.ateapi.v1.GetGlobalAccessPolicyRequest - (*CreateGlobalAccessPolicyRequest)(nil), // 142: substrate.ateapi.v1.CreateGlobalAccessPolicyRequest - (*UpdateGlobalAccessPolicyRequest)(nil), // 143: substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest - (*GetAtespaceAccessPolicyRequest)(nil), // 144: substrate.ateapi.v1.GetAtespaceAccessPolicyRequest - (*CreateAtespaceAccessPolicyRequest)(nil), // 145: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest - (*UpdateAtespaceAccessPolicyRequest)(nil), // 146: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest - (*DeleteAtespaceAccessPolicyRequest)(nil), // 147: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest - (*ResourceAnnotation)(nil), // 148: substrate.ateapi.v1.ResourceAnnotation - (*MethodAnnotation)(nil), // 149: substrate.ateapi.v1.MethodAnnotation - nil, // 150: substrate.ateapi.v1.Selector.MatchLabelsEntry - nil, // 151: substrate.ateapi.v1.ExternalVolumeStatus.VolumeContextEntry - nil, // 152: substrate.ateapi.v1.Worker.LabelsEntry - (*timestamppb.Timestamp)(nil), // 153: google.protobuf.Timestamp - (*descriptorpb.MessageOptions)(nil), // 154: google.protobuf.MessageOptions - (*descriptorpb.MethodOptions)(nil), // 155: google.protobuf.MethodOptions + (*ExternalVolumeClass)(nil), // 54: substrate.ateapi.v1.ExternalVolumeClass + (*SystemInfoVolumeSource)(nil), // 55: substrate.ateapi.v1.SystemInfoVolumeSource + (*SystemInfoDataSource)(nil), // 56: substrate.ateapi.v1.SystemInfoDataSource + (*ActorMetadataDataSource)(nil), // 57: substrate.ateapi.v1.ActorMetadataDataSource + (*ActorMetadataItem)(nil), // 58: substrate.ateapi.v1.ActorMetadataItem + (*TrustBundleDataSource)(nil), // 59: substrate.ateapi.v1.TrustBundleDataSource + (*VolumeMount)(nil), // 60: substrate.ateapi.v1.VolumeMount + (*CreateAtespaceRequest)(nil), // 61: substrate.ateapi.v1.CreateAtespaceRequest + (*GetAtespaceRequest)(nil), // 62: substrate.ateapi.v1.GetAtespaceRequest + (*ListAtespacesRequest)(nil), // 63: substrate.ateapi.v1.ListAtespacesRequest + (*ListAtespacesResponse)(nil), // 64: substrate.ateapi.v1.ListAtespacesResponse + (*DeleteAtespaceRequest)(nil), // 65: substrate.ateapi.v1.DeleteAtespaceRequest + (*CreateActorTemplateRequest)(nil), // 66: substrate.ateapi.v1.CreateActorTemplateRequest + (*GetActorTemplateRequest)(nil), // 67: substrate.ateapi.v1.GetActorTemplateRequest + (*ListActorTemplatesRequest)(nil), // 68: substrate.ateapi.v1.ListActorTemplatesRequest + (*ListActorTemplatesResponse)(nil), // 69: substrate.ateapi.v1.ListActorTemplatesResponse + (*DeleteActorTemplateRequest)(nil), // 70: substrate.ateapi.v1.DeleteActorTemplateRequest + (*GetActorRequest)(nil), // 71: substrate.ateapi.v1.GetActorRequest + (*CreateActorRequest)(nil), // 72: substrate.ateapi.v1.CreateActorRequest + (*UpdateActorRequest)(nil), // 73: substrate.ateapi.v1.UpdateActorRequest + (*SuspendActorRequest)(nil), // 74: substrate.ateapi.v1.SuspendActorRequest + (*SuspendActorResponse)(nil), // 75: substrate.ateapi.v1.SuspendActorResponse + (*SuspendOptions)(nil), // 76: substrate.ateapi.v1.SuspendOptions + (*ResumeActorRequest)(nil), // 77: substrate.ateapi.v1.ResumeActorRequest + (*ResumeActorResponse)(nil), // 78: substrate.ateapi.v1.ResumeActorResponse + (*RevertActorRequest)(nil), // 79: substrate.ateapi.v1.RevertActorRequest + (*RevertActorResponse)(nil), // 80: substrate.ateapi.v1.RevertActorResponse + (*DeleteActorRequest)(nil), // 81: substrate.ateapi.v1.DeleteActorRequest + (*GetActorEgressPolicyRequest)(nil), // 82: substrate.ateapi.v1.GetActorEgressPolicyRequest + (*CreateActorEgressPolicyRequest)(nil), // 83: substrate.ateapi.v1.CreateActorEgressPolicyRequest + (*UpdateActorEgressPolicyRequest)(nil), // 84: substrate.ateapi.v1.UpdateActorEgressPolicyRequest + (*DeleteActorEgressPolicyRequest)(nil), // 85: substrate.ateapi.v1.DeleteActorEgressPolicyRequest + (*GetTagRequest)(nil), // 86: substrate.ateapi.v1.GetTagRequest + (*MintActorJwtRequest)(nil), // 87: substrate.ateapi.v1.MintActorJwtRequest + (*MintActorJwtResponse)(nil), // 88: substrate.ateapi.v1.MintActorJwtResponse + (*ListTagsRequest)(nil), // 89: substrate.ateapi.v1.ListTagsRequest + (*ListTagsResponse)(nil), // 90: substrate.ateapi.v1.ListTagsResponse + (*CreateTagRequest)(nil), // 91: substrate.ateapi.v1.CreateTagRequest + (*UpdateTagRequest)(nil), // 92: substrate.ateapi.v1.UpdateTagRequest + (*DeleteTagRequest)(nil), // 93: substrate.ateapi.v1.DeleteTagRequest + (*DeleteOptions)(nil), // 94: substrate.ateapi.v1.DeleteOptions + (*ListOptions)(nil), // 95: substrate.ateapi.v1.ListOptions + (*ListWorkerActorAssignmentsRequest)(nil), // 96: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest + (*ListWorkerActorAssignmentsResponse)(nil), // 97: substrate.ateapi.v1.ListWorkerActorAssignmentsResponse + (*ListWorkersRequest)(nil), // 98: substrate.ateapi.v1.ListWorkersRequest + (*ListWorkersResponse)(nil), // 99: substrate.ateapi.v1.ListWorkersResponse + (*GetWorkerRequest)(nil), // 100: substrate.ateapi.v1.GetWorkerRequest + (*CreateWorkerRequest)(nil), // 101: substrate.ateapi.v1.CreateWorkerRequest + (*UpdateWorkerRequest)(nil), // 102: substrate.ateapi.v1.UpdateWorkerRequest + (*DeleteWorkerRequest)(nil), // 103: substrate.ateapi.v1.DeleteWorkerRequest + (*DrainWorkerRequest)(nil), // 104: substrate.ateapi.v1.DrainWorkerRequest + (*DrainWorkerResponse)(nil), // 105: substrate.ateapi.v1.DrainWorkerResponse + (*MarkWorkerAvailableRequest)(nil), // 106: substrate.ateapi.v1.MarkWorkerAvailableRequest + (*MarkWorkerAvailableResponse)(nil), // 107: substrate.ateapi.v1.MarkWorkerAvailableResponse + (*MarkWorkerUnavailableRequest)(nil), // 108: substrate.ateapi.v1.MarkWorkerUnavailableRequest + (*MarkWorkerUnavailableResponse)(nil), // 109: substrate.ateapi.v1.MarkWorkerUnavailableResponse + (*ListActorsRequest)(nil), // 110: substrate.ateapi.v1.ListActorsRequest + (*ListActorsResponse)(nil), // 111: substrate.ateapi.v1.ListActorsResponse + (*Worker)(nil), // 112: substrate.ateapi.v1.Worker + (*WorkerStatus)(nil), // 113: substrate.ateapi.v1.WorkerStatus + (*WorkerSandboxClass)(nil), // 114: substrate.ateapi.v1.WorkerSandboxClass + (*WorkerSandboxRuntime)(nil), // 115: substrate.ateapi.v1.WorkerSandboxRuntime + (*RuntimeOverhead)(nil), // 116: substrate.ateapi.v1.RuntimeOverhead + (*ActorSandboxRuntime)(nil), // 117: substrate.ateapi.v1.ActorSandboxRuntime + (*VersionedSandboxCompat)(nil), // 118: substrate.ateapi.v1.VersionedSandboxCompat + (*AttributeEntry)(nil), // 119: substrate.ateapi.v1.AttributeEntry + (*WorkerResources)(nil), // 120: substrate.ateapi.v1.WorkerResources + (*ActorAssignment)(nil), // 121: substrate.ateapi.v1.ActorAssignment + (*AcquireWorkerEpochRequest)(nil), // 122: substrate.ateapi.v1.AcquireWorkerEpochRequest + (*AcquireWorkerEpochResponse)(nil), // 123: substrate.ateapi.v1.AcquireWorkerEpochResponse + (*RegisterWorkerRequest)(nil), // 124: substrate.ateapi.v1.RegisterWorkerRequest + (*RegisterWorkerResponse)(nil), // 125: substrate.ateapi.v1.RegisterWorkerResponse + (*SetWorkerSandboxRuntimesRequest)(nil), // 126: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest + (*SetWorkerSandboxRuntimesResponse)(nil), // 127: substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse + (*MintWorkerActorCertificateRequest)(nil), // 128: substrate.ateapi.v1.MintWorkerActorCertificateRequest + (*MintWorkerActorCertificateResponse)(nil), // 129: substrate.ateapi.v1.MintWorkerActorCertificateResponse + (*MintWorkerActorJwtRequest)(nil), // 130: substrate.ateapi.v1.MintWorkerActorJwtRequest + (*MintWorkerActorJwtResponse)(nil), // 131: substrate.ateapi.v1.MintWorkerActorJwtResponse + (*RequestActorSuspendRequest)(nil), // 132: substrate.ateapi.v1.RequestActorSuspendRequest + (*RequestActorSuspendResponse)(nil), // 133: substrate.ateapi.v1.RequestActorSuspendResponse + (*ReportActorCrashedRequest)(nil), // 134: substrate.ateapi.v1.ReportActorCrashedRequest + (*ReportActorCrashedResponse)(nil), // 135: substrate.ateapi.v1.ReportActorCrashedResponse + (*ReportActorSnapshotStateRequest)(nil), // 136: substrate.ateapi.v1.ReportActorSnapshotStateRequest + (*ReportActorSnapshotStateResponse)(nil), // 137: substrate.ateapi.v1.ReportActorSnapshotStateResponse + (*ActorSnapshotState)(nil), // 138: substrate.ateapi.v1.ActorSnapshotState + (*SnapshotReport)(nil), // 139: substrate.ateapi.v1.SnapshotReport + (*AccessPolicy)(nil), // 140: substrate.ateapi.v1.AccessPolicy + (*Binding)(nil), // 141: substrate.ateapi.v1.Binding + (*GetGlobalAccessPolicyRequest)(nil), // 142: substrate.ateapi.v1.GetGlobalAccessPolicyRequest + (*CreateGlobalAccessPolicyRequest)(nil), // 143: substrate.ateapi.v1.CreateGlobalAccessPolicyRequest + (*UpdateGlobalAccessPolicyRequest)(nil), // 144: substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest + (*GetAtespaceAccessPolicyRequest)(nil), // 145: substrate.ateapi.v1.GetAtespaceAccessPolicyRequest + (*CreateAtespaceAccessPolicyRequest)(nil), // 146: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest + (*UpdateAtespaceAccessPolicyRequest)(nil), // 147: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest + (*DeleteAtespaceAccessPolicyRequest)(nil), // 148: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest + (*ResourceAnnotation)(nil), // 149: substrate.ateapi.v1.ResourceAnnotation + (*MethodAnnotation)(nil), // 150: substrate.ateapi.v1.MethodAnnotation + nil, // 151: substrate.ateapi.v1.Selector.MatchLabelsEntry + nil, // 152: substrate.ateapi.v1.ExternalVolumeStatus.VolumeContextEntry + nil, // 153: substrate.ateapi.v1.ExternalVolumeClass.ParametersEntry + nil, // 154: substrate.ateapi.v1.Worker.LabelsEntry + (*timestamppb.Timestamp)(nil), // 155: google.protobuf.Timestamp + (*descriptorpb.MessageOptions)(nil), // 156: google.protobuf.MessageOptions + (*descriptorpb.MethodOptions)(nil), // 157: google.protobuf.MethodOptions } var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 1, // 0: substrate.ateapi.v1.SnapshotStorage.state:type_name -> substrate.ateapi.v1.SnapshotStorageState @@ -10828,13 +10921,13 @@ var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 0, // 2: substrate.ateapi.v1.Snapshot.owner:type_name -> substrate.ateapi.v1.SnapshotOwner 2, // 3: substrate.ateapi.v1.Snapshot.fidelity:type_name -> substrate.ateapi.v1.SnapshotFidelity 11, // 4: substrate.ateapi.v1.Snapshot.durable_snapshot:type_name -> substrate.ateapi.v1.SnapshotStorage - 116, // 5: substrate.ateapi.v1.Snapshot.sandbox_runtime:type_name -> substrate.ateapi.v1.ActorSandboxRuntime - 150, // 6: substrate.ateapi.v1.Selector.match_labels:type_name -> substrate.ateapi.v1.Selector.MatchLabelsEntry - 153, // 7: substrate.ateapi.v1.ResourceMetadata.create_time:type_name -> google.protobuf.Timestamp - 153, // 8: substrate.ateapi.v1.ResourceMetadata.update_time:type_name -> google.protobuf.Timestamp - 153, // 9: substrate.ateapi.v1.ResourceMetadata.delete_time:type_name -> google.protobuf.Timestamp + 117, // 5: substrate.ateapi.v1.Snapshot.sandbox_runtime:type_name -> substrate.ateapi.v1.ActorSandboxRuntime + 151, // 6: substrate.ateapi.v1.Selector.match_labels:type_name -> substrate.ateapi.v1.Selector.MatchLabelsEntry + 155, // 7: substrate.ateapi.v1.ResourceMetadata.create_time:type_name -> google.protobuf.Timestamp + 155, // 8: substrate.ateapi.v1.ResourceMetadata.update_time:type_name -> google.protobuf.Timestamp + 155, // 9: substrate.ateapi.v1.ResourceMetadata.delete_time:type_name -> google.protobuf.Timestamp 16, // 10: substrate.ateapi.v1.ExternalVolumes.volumes:type_name -> substrate.ateapi.v1.ExternalVolumeStatus - 151, // 11: substrate.ateapi.v1.ExternalVolumeStatus.volume_context:type_name -> substrate.ateapi.v1.ExternalVolumeStatus.VolumeContextEntry + 152, // 11: substrate.ateapi.v1.ExternalVolumeStatus.volume_context:type_name -> substrate.ateapi.v1.ExternalVolumeStatus.VolumeContextEntry 14, // 12: substrate.ateapi.v1.Actor.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata 35, // 13: substrate.ateapi.v1.Actor.actor_template:type_name -> substrate.ateapi.v1.ObjectRef 13, // 14: substrate.ateapi.v1.Actor.worker_selector:type_name -> substrate.ateapi.v1.Selector @@ -10859,9 +10952,9 @@ var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 15, // 33: substrate.ateapi.v1.ActorStatus.external_volumes:type_name -> substrate.ateapi.v1.ExternalVolumes 30, // 34: substrate.ateapi.v1.ActorStatus.crash:type_name -> substrate.ateapi.v1.ActorCrash 12, // 35: substrate.ateapi.v1.ActorStatus.snapshots:type_name -> substrate.ateapi.v1.Snapshot - 153, // 36: substrate.ateapi.v1.ActorCrash.crash_time:type_name -> google.protobuf.Timestamp + 155, // 36: substrate.ateapi.v1.ActorCrash.crash_time:type_name -> google.protobuf.Timestamp 35, // 37: substrate.ateapi.v1.WorkerAssignment.worker:type_name -> substrate.ateapi.v1.ObjectRef - 116, // 38: substrate.ateapi.v1.WorkerAssignment.sandbox_runtime:type_name -> substrate.ateapi.v1.ActorSandboxRuntime + 117, // 38: substrate.ateapi.v1.WorkerAssignment.sandbox_runtime:type_name -> substrate.ateapi.v1.ActorSandboxRuntime 12, // 39: substrate.ateapi.v1.TagStatus.snapshot:type_name -> substrate.ateapi.v1.Snapshot 14, // 40: substrate.ateapi.v1.Tag.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata 32, // 41: substrate.ateapi.v1.Tag.status:type_name -> substrate.ateapi.v1.TagStatus @@ -10878,251 +10971,253 @@ var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 40, // 52: substrate.ateapi.v1.ActorTemplate.status:type_name -> substrate.ateapi.v1.ActorTemplateStatus 38, // 53: substrate.ateapi.v1.ResourceRequirements.limits:type_name -> substrate.ateapi.v1.Resources 35, // 54: substrate.ateapi.v1.GoldenSnapshotStatus.golden_tag:type_name -> substrate.ateapi.v1.ObjectRef - 153, // 55: substrate.ateapi.v1.GoldenSnapshotStatus.snapshot_time:type_name -> google.protobuf.Timestamp + 155, // 55: substrate.ateapi.v1.GoldenSnapshotStatus.snapshot_time:type_name -> google.protobuf.Timestamp 39, // 56: substrate.ateapi.v1.ActorTemplateStatus.golden_snapshot_status:type_name -> substrate.ateapi.v1.GoldenSnapshotStatus 2, // 57: substrate.ateapi.v1.SnapshotConfig.preferred_fidelity:type_name -> substrate.ateapi.v1.SnapshotFidelity 42, // 58: substrate.ateapi.v1.SnapshotConfig.golden_snapshot_config:type_name -> substrate.ateapi.v1.GoldenSnapshotConfig 5, // 59: substrate.ateapi.v1.GoldenSnapshotConfig.mode:type_name -> substrate.ateapi.v1.GoldenSnapshotMode 46, // 60: substrate.ateapi.v1.Container.env:type_name -> substrate.ateapi.v1.EnvVar 47, // 61: substrate.ateapi.v1.Container.wakeup_probe:type_name -> substrate.ateapi.v1.WakeupProbe - 59, // 62: substrate.ateapi.v1.Container.volume_mounts:type_name -> substrate.ateapi.v1.VolumeMount + 60, // 62: substrate.ateapi.v1.Container.volume_mounts:type_name -> substrate.ateapi.v1.VolumeMount 44, // 63: substrate.ateapi.v1.Container.security_context:type_name -> substrate.ateapi.v1.SecurityContext 37, // 64: substrate.ateapi.v1.Container.resources:type_name -> substrate.ateapi.v1.ResourceRequirements 45, // 65: substrate.ateapi.v1.SecurityContext.capabilities:type_name -> substrate.ateapi.v1.Capabilities 48, // 66: substrate.ateapi.v1.WakeupProbe.http_get:type_name -> substrate.ateapi.v1.HttpGetAction 52, // 67: substrate.ateapi.v1.Volume.durable_dir:type_name -> substrate.ateapi.v1.DurableDirVolumeSource 50, // 68: substrate.ateapi.v1.Volume.external:type_name -> substrate.ateapi.v1.ExternalVolumeSource - 54, // 69: substrate.ateapi.v1.Volume.system_info:type_name -> substrate.ateapi.v1.SystemInfoVolumeSource + 55, // 69: substrate.ateapi.v1.Volume.system_info:type_name -> substrate.ateapi.v1.SystemInfoVolumeSource 51, // 70: substrate.ateapi.v1.Volume.image:type_name -> substrate.ateapi.v1.ImageVolumeSource 53, // 71: substrate.ateapi.v1.ExternalVolumeSource.template:type_name -> substrate.ateapi.v1.ExternalVolumeTemplate - 55, // 72: substrate.ateapi.v1.SystemInfoVolumeSource.data_sources:type_name -> substrate.ateapi.v1.SystemInfoDataSource - 56, // 73: substrate.ateapi.v1.SystemInfoDataSource.actor_metadata:type_name -> substrate.ateapi.v1.ActorMetadataDataSource - 58, // 74: substrate.ateapi.v1.SystemInfoDataSource.trust_bundle:type_name -> substrate.ateapi.v1.TrustBundleDataSource - 57, // 75: substrate.ateapi.v1.ActorMetadataDataSource.items:type_name -> substrate.ateapi.v1.ActorMetadataItem - 6, // 76: substrate.ateapi.v1.ActorMetadataItem.field:type_name -> substrate.ateapi.v1.ActorMetadataField - 34, // 77: substrate.ateapi.v1.CreateAtespaceRequest.atespace:type_name -> substrate.ateapi.v1.Atespace - 35, // 78: substrate.ateapi.v1.GetAtespaceRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef - 94, // 79: substrate.ateapi.v1.ListAtespacesRequest.options:type_name -> substrate.ateapi.v1.ListOptions - 34, // 80: substrate.ateapi.v1.ListAtespacesResponse.atespaces:type_name -> substrate.ateapi.v1.Atespace - 35, // 81: substrate.ateapi.v1.DeleteAtespaceRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef - 93, // 82: substrate.ateapi.v1.DeleteAtespaceRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions - 36, // 83: substrate.ateapi.v1.CreateActorTemplateRequest.actor_template:type_name -> substrate.ateapi.v1.ActorTemplate - 35, // 84: substrate.ateapi.v1.GetActorTemplateRequest.actor_template:type_name -> substrate.ateapi.v1.ObjectRef - 94, // 85: substrate.ateapi.v1.ListActorTemplatesRequest.options:type_name -> substrate.ateapi.v1.ListOptions - 36, // 86: substrate.ateapi.v1.ListActorTemplatesResponse.actor_templates:type_name -> substrate.ateapi.v1.ActorTemplate - 35, // 87: substrate.ateapi.v1.DeleteActorTemplateRequest.actor_template:type_name -> substrate.ateapi.v1.ObjectRef - 93, // 88: substrate.ateapi.v1.DeleteActorTemplateRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions - 35, // 89: substrate.ateapi.v1.GetActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 17, // 90: substrate.ateapi.v1.CreateActorRequest.actor:type_name -> substrate.ateapi.v1.Actor - 17, // 91: substrate.ateapi.v1.UpdateActorRequest.actor:type_name -> substrate.ateapi.v1.Actor - 35, // 92: substrate.ateapi.v1.SuspendActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 75, // 93: substrate.ateapi.v1.SuspendActorRequest.options:type_name -> substrate.ateapi.v1.SuspendOptions - 17, // 94: substrate.ateapi.v1.SuspendActorResponse.actor:type_name -> substrate.ateapi.v1.Actor - 7, // 95: substrate.ateapi.v1.SuspendOptions.mode:type_name -> substrate.ateapi.v1.DurabilityMode - 35, // 96: substrate.ateapi.v1.ResumeActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 17, // 97: substrate.ateapi.v1.ResumeActorResponse.actor:type_name -> substrate.ateapi.v1.Actor - 35, // 98: substrate.ateapi.v1.RevertActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 17, // 99: substrate.ateapi.v1.RevertActorResponse.actor:type_name -> substrate.ateapi.v1.Actor - 35, // 100: substrate.ateapi.v1.DeleteActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 93, // 101: substrate.ateapi.v1.DeleteActorRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions - 35, // 102: substrate.ateapi.v1.GetActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 103: substrate.ateapi.v1.CreateActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 18, // 104: substrate.ateapi.v1.CreateActorEgressPolicyRequest.egress_policy:type_name -> substrate.ateapi.v1.EgressPolicy - 35, // 105: substrate.ateapi.v1.UpdateActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 18, // 106: substrate.ateapi.v1.UpdateActorEgressPolicyRequest.egress_policy:type_name -> substrate.ateapi.v1.EgressPolicy - 35, // 107: substrate.ateapi.v1.DeleteActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 93, // 108: substrate.ateapi.v1.DeleteActorEgressPolicyRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions - 35, // 109: substrate.ateapi.v1.GetTagRequest.tag:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 110: substrate.ateapi.v1.MintActorJwtRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 153, // 111: substrate.ateapi.v1.MintActorJwtResponse.expire_time:type_name -> google.protobuf.Timestamp - 94, // 112: substrate.ateapi.v1.ListTagsRequest.options:type_name -> substrate.ateapi.v1.ListOptions - 33, // 113: substrate.ateapi.v1.ListTagsResponse.tags:type_name -> substrate.ateapi.v1.Tag - 33, // 114: substrate.ateapi.v1.CreateTagRequest.tag:type_name -> substrate.ateapi.v1.Tag - 33, // 115: substrate.ateapi.v1.UpdateTagRequest.tag:type_name -> substrate.ateapi.v1.Tag - 35, // 116: substrate.ateapi.v1.DeleteTagRequest.tag:type_name -> substrate.ateapi.v1.ObjectRef - 93, // 117: substrate.ateapi.v1.DeleteTagRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions - 35, // 118: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 94, // 119: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest.options:type_name -> substrate.ateapi.v1.ListOptions - 120, // 120: substrate.ateapi.v1.ListWorkerActorAssignmentsResponse.actor_assignments:type_name -> substrate.ateapi.v1.ActorAssignment - 94, // 121: substrate.ateapi.v1.ListWorkersRequest.options:type_name -> substrate.ateapi.v1.ListOptions - 111, // 122: substrate.ateapi.v1.ListWorkersResponse.workers:type_name -> substrate.ateapi.v1.Worker - 35, // 123: substrate.ateapi.v1.GetWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 111, // 124: substrate.ateapi.v1.CreateWorkerRequest.worker:type_name -> substrate.ateapi.v1.Worker - 111, // 125: substrate.ateapi.v1.UpdateWorkerRequest.worker:type_name -> substrate.ateapi.v1.Worker - 35, // 126: substrate.ateapi.v1.DeleteWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 93, // 127: substrate.ateapi.v1.DeleteWorkerRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions - 35, // 128: substrate.ateapi.v1.DrainWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 111, // 129: substrate.ateapi.v1.DrainWorkerResponse.worker:type_name -> substrate.ateapi.v1.Worker - 35, // 130: substrate.ateapi.v1.MarkWorkerAvailableRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 111, // 131: substrate.ateapi.v1.MarkWorkerAvailableResponse.worker:type_name -> substrate.ateapi.v1.Worker - 35, // 132: substrate.ateapi.v1.MarkWorkerUnavailableRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 111, // 133: substrate.ateapi.v1.MarkWorkerUnavailableResponse.worker:type_name -> substrate.ateapi.v1.Worker - 94, // 134: substrate.ateapi.v1.ListActorsRequest.options:type_name -> substrate.ateapi.v1.ListOptions - 17, // 135: substrate.ateapi.v1.ListActorsResponse.actors:type_name -> substrate.ateapi.v1.Actor - 14, // 136: substrate.ateapi.v1.Worker.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata - 152, // 137: substrate.ateapi.v1.Worker.labels:type_name -> substrate.ateapi.v1.Worker.LabelsEntry - 112, // 138: substrate.ateapi.v1.Worker.status:type_name -> substrate.ateapi.v1.WorkerStatus - 8, // 139: substrate.ateapi.v1.WorkerStatus.state:type_name -> substrate.ateapi.v1.WorkerState - 119, // 140: substrate.ateapi.v1.WorkerStatus.capacity:type_name -> substrate.ateapi.v1.WorkerResources - 119, // 141: substrate.ateapi.v1.WorkerStatus.allocated:type_name -> substrate.ateapi.v1.WorkerResources - 113, // 142: substrate.ateapi.v1.WorkerStatus.sandbox_classes:type_name -> substrate.ateapi.v1.WorkerSandboxClass - 114, // 143: substrate.ateapi.v1.WorkerSandboxClass.default_runtime:type_name -> substrate.ateapi.v1.WorkerSandboxRuntime - 114, // 144: substrate.ateapi.v1.WorkerSandboxClass.restorable_runtimes:type_name -> substrate.ateapi.v1.WorkerSandboxRuntime - 117, // 145: substrate.ateapi.v1.WorkerSandboxRuntime.version:type_name -> substrate.ateapi.v1.VersionedSandboxCompat - 115, // 146: substrate.ateapi.v1.WorkerSandboxRuntime.actor_overhead:type_name -> substrate.ateapi.v1.RuntimeOverhead - 117, // 147: substrate.ateapi.v1.ActorSandboxRuntime.version:type_name -> substrate.ateapi.v1.VersionedSandboxCompat - 118, // 148: substrate.ateapi.v1.VersionedSandboxCompat.attributes:type_name -> substrate.ateapi.v1.AttributeEntry - 14, // 149: substrate.ateapi.v1.ActorAssignment.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata - 35, // 150: substrate.ateapi.v1.ActorAssignment.actor:type_name -> substrate.ateapi.v1.ObjectRef - 38, // 151: substrate.ateapi.v1.ActorAssignment.resources:type_name -> substrate.ateapi.v1.Resources - 35, // 152: substrate.ateapi.v1.AcquireWorkerEpochRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 153: substrate.ateapi.v1.RegisterWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 119, // 154: substrate.ateapi.v1.RegisterWorkerRequest.capacity:type_name -> substrate.ateapi.v1.WorkerResources - 111, // 155: substrate.ateapi.v1.RegisterWorkerResponse.worker:type_name -> substrate.ateapi.v1.Worker - 35, // 156: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 113, // 157: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest.sandbox_classes:type_name -> substrate.ateapi.v1.WorkerSandboxClass - 111, // 158: substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse.worker:type_name -> substrate.ateapi.v1.Worker - 35, // 159: substrate.ateapi.v1.MintWorkerActorCertificateRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 160: substrate.ateapi.v1.MintWorkerActorCertificateRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 161: substrate.ateapi.v1.MintWorkerActorJwtRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 153, // 162: substrate.ateapi.v1.MintWorkerActorJwtResponse.expire_time:type_name -> google.protobuf.Timestamp - 35, // 163: substrate.ateapi.v1.RequestActorSuspendRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 164: substrate.ateapi.v1.RequestActorSuspendRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 17, // 165: substrate.ateapi.v1.RequestActorSuspendResponse.actor:type_name -> substrate.ateapi.v1.Actor - 35, // 166: substrate.ateapi.v1.ReportActorCrashedRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 167: substrate.ateapi.v1.ReportActorCrashedRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 17, // 168: substrate.ateapi.v1.ReportActorCrashedResponse.actor:type_name -> substrate.ateapi.v1.Actor - 35, // 169: substrate.ateapi.v1.ReportActorSnapshotStateRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 137, // 170: substrate.ateapi.v1.ReportActorSnapshotStateRequest.state:type_name -> substrate.ateapi.v1.ActorSnapshotState - 138, // 171: substrate.ateapi.v1.ActorSnapshotState.latest_local:type_name -> substrate.ateapi.v1.SnapshotReport - 138, // 172: substrate.ateapi.v1.ActorSnapshotState.uploading:type_name -> substrate.ateapi.v1.SnapshotReport - 138, // 173: substrate.ateapi.v1.ActorSnapshotState.latest_durable:type_name -> substrate.ateapi.v1.SnapshotReport - 153, // 174: substrate.ateapi.v1.ActorSnapshotState.upload_due_time:type_name -> google.protobuf.Timestamp - 2, // 175: substrate.ateapi.v1.SnapshotReport.fidelity:type_name -> substrate.ateapi.v1.SnapshotFidelity - 10, // 176: substrate.ateapi.v1.SnapshotReport.object:type_name -> substrate.ateapi.v1.ObjectSnapshot - 153, // 177: substrate.ateapi.v1.SnapshotReport.local_commit_time:type_name -> google.protobuf.Timestamp - 153, // 178: substrate.ateapi.v1.SnapshotReport.durable_complete_time:type_name -> google.protobuf.Timestamp - 14, // 179: substrate.ateapi.v1.AccessPolicy.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata - 140, // 180: substrate.ateapi.v1.AccessPolicy.bindings:type_name -> substrate.ateapi.v1.Binding - 139, // 181: substrate.ateapi.v1.CreateGlobalAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy - 139, // 182: substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy - 35, // 183: substrate.ateapi.v1.GetAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 184: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef - 139, // 185: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy - 35, // 186: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef - 139, // 187: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy - 35, // 188: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef - 93, // 189: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions - 9, // 190: substrate.ateapi.v1.ResourceAnnotation.scope:type_name -> substrate.ateapi.v1.Scope - 154, // 191: substrate.ateapi.v1.resource:extendee -> google.protobuf.MessageOptions - 155, // 192: substrate.ateapi.v1.method:extendee -> google.protobuf.MethodOptions - 148, // 193: substrate.ateapi.v1.resource:type_name -> substrate.ateapi.v1.ResourceAnnotation - 149, // 194: substrate.ateapi.v1.method:type_name -> substrate.ateapi.v1.MethodAnnotation - 70, // 195: substrate.ateapi.v1.Control.GetActor:input_type -> substrate.ateapi.v1.GetActorRequest - 71, // 196: substrate.ateapi.v1.Control.CreateActor:input_type -> substrate.ateapi.v1.CreateActorRequest - 72, // 197: substrate.ateapi.v1.Control.UpdateActor:input_type -> substrate.ateapi.v1.UpdateActorRequest - 73, // 198: substrate.ateapi.v1.Control.SuspendActor:input_type -> substrate.ateapi.v1.SuspendActorRequest - 76, // 199: substrate.ateapi.v1.Control.ResumeActor:input_type -> substrate.ateapi.v1.ResumeActorRequest - 78, // 200: substrate.ateapi.v1.Control.RevertActor:input_type -> substrate.ateapi.v1.RevertActorRequest - 80, // 201: substrate.ateapi.v1.Control.DeleteActor:input_type -> substrate.ateapi.v1.DeleteActorRequest - 81, // 202: substrate.ateapi.v1.Control.GetActorEgressPolicy:input_type -> substrate.ateapi.v1.GetActorEgressPolicyRequest - 82, // 203: substrate.ateapi.v1.Control.CreateActorEgressPolicy:input_type -> substrate.ateapi.v1.CreateActorEgressPolicyRequest - 83, // 204: substrate.ateapi.v1.Control.UpdateActorEgressPolicy:input_type -> substrate.ateapi.v1.UpdateActorEgressPolicyRequest - 84, // 205: substrate.ateapi.v1.Control.DeleteActorEgressPolicy:input_type -> substrate.ateapi.v1.DeleteActorEgressPolicyRequest - 86, // 206: substrate.ateapi.v1.Control.MintActorJwt:input_type -> substrate.ateapi.v1.MintActorJwtRequest - 90, // 207: substrate.ateapi.v1.Control.CreateTag:input_type -> substrate.ateapi.v1.CreateTagRequest - 85, // 208: substrate.ateapi.v1.Control.GetTag:input_type -> substrate.ateapi.v1.GetTagRequest - 88, // 209: substrate.ateapi.v1.Control.ListTags:input_type -> substrate.ateapi.v1.ListTagsRequest - 91, // 210: substrate.ateapi.v1.Control.UpdateTag:input_type -> substrate.ateapi.v1.UpdateTagRequest - 92, // 211: substrate.ateapi.v1.Control.DeleteTag:input_type -> substrate.ateapi.v1.DeleteTagRequest - 97, // 212: substrate.ateapi.v1.Control.ListWorkers:input_type -> substrate.ateapi.v1.ListWorkersRequest - 99, // 213: substrate.ateapi.v1.Control.GetWorker:input_type -> substrate.ateapi.v1.GetWorkerRequest - 100, // 214: substrate.ateapi.v1.Control.CreateWorker:input_type -> substrate.ateapi.v1.CreateWorkerRequest - 101, // 215: substrate.ateapi.v1.Control.UpdateWorker:input_type -> substrate.ateapi.v1.UpdateWorkerRequest - 102, // 216: substrate.ateapi.v1.Control.DeleteWorker:input_type -> substrate.ateapi.v1.DeleteWorkerRequest - 103, // 217: substrate.ateapi.v1.Control.DrainWorker:input_type -> substrate.ateapi.v1.DrainWorkerRequest - 105, // 218: substrate.ateapi.v1.Control.MarkWorkerAvailable:input_type -> substrate.ateapi.v1.MarkWorkerAvailableRequest - 107, // 219: substrate.ateapi.v1.Control.MarkWorkerUnavailable:input_type -> substrate.ateapi.v1.MarkWorkerUnavailableRequest - 95, // 220: substrate.ateapi.v1.Control.ListWorkerActorAssignments:input_type -> substrate.ateapi.v1.ListWorkerActorAssignmentsRequest - 109, // 221: substrate.ateapi.v1.Control.ListActors:input_type -> substrate.ateapi.v1.ListActorsRequest - 60, // 222: substrate.ateapi.v1.Control.CreateAtespace:input_type -> substrate.ateapi.v1.CreateAtespaceRequest - 61, // 223: substrate.ateapi.v1.Control.GetAtespace:input_type -> substrate.ateapi.v1.GetAtespaceRequest - 62, // 224: substrate.ateapi.v1.Control.ListAtespaces:input_type -> substrate.ateapi.v1.ListAtespacesRequest - 64, // 225: substrate.ateapi.v1.Control.DeleteAtespace:input_type -> substrate.ateapi.v1.DeleteAtespaceRequest - 65, // 226: substrate.ateapi.v1.Control.CreateActorTemplate:input_type -> substrate.ateapi.v1.CreateActorTemplateRequest - 66, // 227: substrate.ateapi.v1.Control.GetActorTemplate:input_type -> substrate.ateapi.v1.GetActorTemplateRequest - 67, // 228: substrate.ateapi.v1.Control.ListActorTemplates:input_type -> substrate.ateapi.v1.ListActorTemplatesRequest - 69, // 229: substrate.ateapi.v1.Control.DeleteActorTemplate:input_type -> substrate.ateapi.v1.DeleteActorTemplateRequest - 141, // 230: substrate.ateapi.v1.Control.GetGlobalAccessPolicy:input_type -> substrate.ateapi.v1.GetGlobalAccessPolicyRequest - 142, // 231: substrate.ateapi.v1.Control.CreateGlobalAccessPolicy:input_type -> substrate.ateapi.v1.CreateGlobalAccessPolicyRequest - 143, // 232: substrate.ateapi.v1.Control.UpdateGlobalAccessPolicy:input_type -> substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest - 144, // 233: substrate.ateapi.v1.Control.GetAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.GetAtespaceAccessPolicyRequest - 145, // 234: substrate.ateapi.v1.Control.CreateAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest - 146, // 235: substrate.ateapi.v1.Control.UpdateAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest - 147, // 236: substrate.ateapi.v1.Control.DeleteAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest - 121, // 237: substrate.ateapi.v1.WorkerService.AcquireWorkerEpoch:input_type -> substrate.ateapi.v1.AcquireWorkerEpochRequest - 123, // 238: substrate.ateapi.v1.WorkerService.RegisterWorker:input_type -> substrate.ateapi.v1.RegisterWorkerRequest - 125, // 239: substrate.ateapi.v1.WorkerService.SetWorkerSandboxRuntimes:input_type -> substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest - 127, // 240: substrate.ateapi.v1.WorkerService.MintWorkerActorCertificate:input_type -> substrate.ateapi.v1.MintWorkerActorCertificateRequest - 129, // 241: substrate.ateapi.v1.WorkerService.MintWorkerActorJwt:input_type -> substrate.ateapi.v1.MintWorkerActorJwtRequest - 131, // 242: substrate.ateapi.v1.WorkerService.RequestActorSuspend:input_type -> substrate.ateapi.v1.RequestActorSuspendRequest - 135, // 243: substrate.ateapi.v1.WorkerService.ReportActorSnapshotState:input_type -> substrate.ateapi.v1.ReportActorSnapshotStateRequest - 133, // 244: substrate.ateapi.v1.WorkerService.ReportActorCrashed:input_type -> substrate.ateapi.v1.ReportActorCrashedRequest - 17, // 245: substrate.ateapi.v1.Control.GetActor:output_type -> substrate.ateapi.v1.Actor - 17, // 246: substrate.ateapi.v1.Control.CreateActor:output_type -> substrate.ateapi.v1.Actor - 17, // 247: substrate.ateapi.v1.Control.UpdateActor:output_type -> substrate.ateapi.v1.Actor - 74, // 248: substrate.ateapi.v1.Control.SuspendActor:output_type -> substrate.ateapi.v1.SuspendActorResponse - 77, // 249: substrate.ateapi.v1.Control.ResumeActor:output_type -> substrate.ateapi.v1.ResumeActorResponse - 79, // 250: substrate.ateapi.v1.Control.RevertActor:output_type -> substrate.ateapi.v1.RevertActorResponse - 17, // 251: substrate.ateapi.v1.Control.DeleteActor:output_type -> substrate.ateapi.v1.Actor - 18, // 252: substrate.ateapi.v1.Control.GetActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy - 18, // 253: substrate.ateapi.v1.Control.CreateActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy - 18, // 254: substrate.ateapi.v1.Control.UpdateActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy - 18, // 255: substrate.ateapi.v1.Control.DeleteActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy - 87, // 256: substrate.ateapi.v1.Control.MintActorJwt:output_type -> substrate.ateapi.v1.MintActorJwtResponse - 33, // 257: substrate.ateapi.v1.Control.CreateTag:output_type -> substrate.ateapi.v1.Tag - 33, // 258: substrate.ateapi.v1.Control.GetTag:output_type -> substrate.ateapi.v1.Tag - 89, // 259: substrate.ateapi.v1.Control.ListTags:output_type -> substrate.ateapi.v1.ListTagsResponse - 33, // 260: substrate.ateapi.v1.Control.UpdateTag:output_type -> substrate.ateapi.v1.Tag - 33, // 261: substrate.ateapi.v1.Control.DeleteTag:output_type -> substrate.ateapi.v1.Tag - 98, // 262: substrate.ateapi.v1.Control.ListWorkers:output_type -> substrate.ateapi.v1.ListWorkersResponse - 111, // 263: substrate.ateapi.v1.Control.GetWorker:output_type -> substrate.ateapi.v1.Worker - 111, // 264: substrate.ateapi.v1.Control.CreateWorker:output_type -> substrate.ateapi.v1.Worker - 111, // 265: substrate.ateapi.v1.Control.UpdateWorker:output_type -> substrate.ateapi.v1.Worker - 111, // 266: substrate.ateapi.v1.Control.DeleteWorker:output_type -> substrate.ateapi.v1.Worker - 104, // 267: substrate.ateapi.v1.Control.DrainWorker:output_type -> substrate.ateapi.v1.DrainWorkerResponse - 106, // 268: substrate.ateapi.v1.Control.MarkWorkerAvailable:output_type -> substrate.ateapi.v1.MarkWorkerAvailableResponse - 108, // 269: substrate.ateapi.v1.Control.MarkWorkerUnavailable:output_type -> substrate.ateapi.v1.MarkWorkerUnavailableResponse - 96, // 270: substrate.ateapi.v1.Control.ListWorkerActorAssignments:output_type -> substrate.ateapi.v1.ListWorkerActorAssignmentsResponse - 110, // 271: substrate.ateapi.v1.Control.ListActors:output_type -> substrate.ateapi.v1.ListActorsResponse - 34, // 272: substrate.ateapi.v1.Control.CreateAtespace:output_type -> substrate.ateapi.v1.Atespace - 34, // 273: substrate.ateapi.v1.Control.GetAtespace:output_type -> substrate.ateapi.v1.Atespace - 63, // 274: substrate.ateapi.v1.Control.ListAtespaces:output_type -> substrate.ateapi.v1.ListAtespacesResponse - 34, // 275: substrate.ateapi.v1.Control.DeleteAtespace:output_type -> substrate.ateapi.v1.Atespace - 36, // 276: substrate.ateapi.v1.Control.CreateActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate - 36, // 277: substrate.ateapi.v1.Control.GetActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate - 68, // 278: substrate.ateapi.v1.Control.ListActorTemplates:output_type -> substrate.ateapi.v1.ListActorTemplatesResponse - 36, // 279: substrate.ateapi.v1.Control.DeleteActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate - 139, // 280: substrate.ateapi.v1.Control.GetGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 139, // 281: substrate.ateapi.v1.Control.CreateGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 139, // 282: substrate.ateapi.v1.Control.UpdateGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 139, // 283: substrate.ateapi.v1.Control.GetAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 139, // 284: substrate.ateapi.v1.Control.CreateAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 139, // 285: substrate.ateapi.v1.Control.UpdateAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 139, // 286: substrate.ateapi.v1.Control.DeleteAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 122, // 287: substrate.ateapi.v1.WorkerService.AcquireWorkerEpoch:output_type -> substrate.ateapi.v1.AcquireWorkerEpochResponse - 124, // 288: substrate.ateapi.v1.WorkerService.RegisterWorker:output_type -> substrate.ateapi.v1.RegisterWorkerResponse - 126, // 289: substrate.ateapi.v1.WorkerService.SetWorkerSandboxRuntimes:output_type -> substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse - 128, // 290: substrate.ateapi.v1.WorkerService.MintWorkerActorCertificate:output_type -> substrate.ateapi.v1.MintWorkerActorCertificateResponse - 130, // 291: substrate.ateapi.v1.WorkerService.MintWorkerActorJwt:output_type -> substrate.ateapi.v1.MintWorkerActorJwtResponse - 132, // 292: substrate.ateapi.v1.WorkerService.RequestActorSuspend:output_type -> substrate.ateapi.v1.RequestActorSuspendResponse - 136, // 293: substrate.ateapi.v1.WorkerService.ReportActorSnapshotState:output_type -> substrate.ateapi.v1.ReportActorSnapshotStateResponse - 134, // 294: substrate.ateapi.v1.WorkerService.ReportActorCrashed:output_type -> substrate.ateapi.v1.ReportActorCrashedResponse - 245, // [245:295] is the sub-list for method output_type - 195, // [195:245] is the sub-list for method input_type - 193, // [193:195] is the sub-list for extension type_name - 191, // [191:193] is the sub-list for extension extendee - 0, // [0:191] is the sub-list for field type_name + 14, // 72: substrate.ateapi.v1.ExternalVolumeClass.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata + 153, // 73: substrate.ateapi.v1.ExternalVolumeClass.parameters:type_name -> substrate.ateapi.v1.ExternalVolumeClass.ParametersEntry + 56, // 74: substrate.ateapi.v1.SystemInfoVolumeSource.data_sources:type_name -> substrate.ateapi.v1.SystemInfoDataSource + 57, // 75: substrate.ateapi.v1.SystemInfoDataSource.actor_metadata:type_name -> substrate.ateapi.v1.ActorMetadataDataSource + 59, // 76: substrate.ateapi.v1.SystemInfoDataSource.trust_bundle:type_name -> substrate.ateapi.v1.TrustBundleDataSource + 58, // 77: substrate.ateapi.v1.ActorMetadataDataSource.items:type_name -> substrate.ateapi.v1.ActorMetadataItem + 6, // 78: substrate.ateapi.v1.ActorMetadataItem.field:type_name -> substrate.ateapi.v1.ActorMetadataField + 34, // 79: substrate.ateapi.v1.CreateAtespaceRequest.atespace:type_name -> substrate.ateapi.v1.Atespace + 35, // 80: substrate.ateapi.v1.GetAtespaceRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef + 95, // 81: substrate.ateapi.v1.ListAtespacesRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 34, // 82: substrate.ateapi.v1.ListAtespacesResponse.atespaces:type_name -> substrate.ateapi.v1.Atespace + 35, // 83: substrate.ateapi.v1.DeleteAtespaceRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef + 94, // 84: substrate.ateapi.v1.DeleteAtespaceRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 36, // 85: substrate.ateapi.v1.CreateActorTemplateRequest.actor_template:type_name -> substrate.ateapi.v1.ActorTemplate + 35, // 86: substrate.ateapi.v1.GetActorTemplateRequest.actor_template:type_name -> substrate.ateapi.v1.ObjectRef + 95, // 87: substrate.ateapi.v1.ListActorTemplatesRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 36, // 88: substrate.ateapi.v1.ListActorTemplatesResponse.actor_templates:type_name -> substrate.ateapi.v1.ActorTemplate + 35, // 89: substrate.ateapi.v1.DeleteActorTemplateRequest.actor_template:type_name -> substrate.ateapi.v1.ObjectRef + 94, // 90: substrate.ateapi.v1.DeleteActorTemplateRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 35, // 91: substrate.ateapi.v1.GetActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 17, // 92: substrate.ateapi.v1.CreateActorRequest.actor:type_name -> substrate.ateapi.v1.Actor + 17, // 93: substrate.ateapi.v1.UpdateActorRequest.actor:type_name -> substrate.ateapi.v1.Actor + 35, // 94: substrate.ateapi.v1.SuspendActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 76, // 95: substrate.ateapi.v1.SuspendActorRequest.options:type_name -> substrate.ateapi.v1.SuspendOptions + 17, // 96: substrate.ateapi.v1.SuspendActorResponse.actor:type_name -> substrate.ateapi.v1.Actor + 7, // 97: substrate.ateapi.v1.SuspendOptions.mode:type_name -> substrate.ateapi.v1.DurabilityMode + 35, // 98: substrate.ateapi.v1.ResumeActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 17, // 99: substrate.ateapi.v1.ResumeActorResponse.actor:type_name -> substrate.ateapi.v1.Actor + 35, // 100: substrate.ateapi.v1.RevertActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 17, // 101: substrate.ateapi.v1.RevertActorResponse.actor:type_name -> substrate.ateapi.v1.Actor + 35, // 102: substrate.ateapi.v1.DeleteActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 94, // 103: substrate.ateapi.v1.DeleteActorRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 35, // 104: substrate.ateapi.v1.GetActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 105: substrate.ateapi.v1.CreateActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 18, // 106: substrate.ateapi.v1.CreateActorEgressPolicyRequest.egress_policy:type_name -> substrate.ateapi.v1.EgressPolicy + 35, // 107: substrate.ateapi.v1.UpdateActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 18, // 108: substrate.ateapi.v1.UpdateActorEgressPolicyRequest.egress_policy:type_name -> substrate.ateapi.v1.EgressPolicy + 35, // 109: substrate.ateapi.v1.DeleteActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 94, // 110: substrate.ateapi.v1.DeleteActorEgressPolicyRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 35, // 111: substrate.ateapi.v1.GetTagRequest.tag:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 112: substrate.ateapi.v1.MintActorJwtRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 155, // 113: substrate.ateapi.v1.MintActorJwtResponse.expire_time:type_name -> google.protobuf.Timestamp + 95, // 114: substrate.ateapi.v1.ListTagsRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 33, // 115: substrate.ateapi.v1.ListTagsResponse.tags:type_name -> substrate.ateapi.v1.Tag + 33, // 116: substrate.ateapi.v1.CreateTagRequest.tag:type_name -> substrate.ateapi.v1.Tag + 33, // 117: substrate.ateapi.v1.UpdateTagRequest.tag:type_name -> substrate.ateapi.v1.Tag + 35, // 118: substrate.ateapi.v1.DeleteTagRequest.tag:type_name -> substrate.ateapi.v1.ObjectRef + 94, // 119: substrate.ateapi.v1.DeleteTagRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 35, // 120: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 95, // 121: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 121, // 122: substrate.ateapi.v1.ListWorkerActorAssignmentsResponse.actor_assignments:type_name -> substrate.ateapi.v1.ActorAssignment + 95, // 123: substrate.ateapi.v1.ListWorkersRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 112, // 124: substrate.ateapi.v1.ListWorkersResponse.workers:type_name -> substrate.ateapi.v1.Worker + 35, // 125: substrate.ateapi.v1.GetWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 112, // 126: substrate.ateapi.v1.CreateWorkerRequest.worker:type_name -> substrate.ateapi.v1.Worker + 112, // 127: substrate.ateapi.v1.UpdateWorkerRequest.worker:type_name -> substrate.ateapi.v1.Worker + 35, // 128: substrate.ateapi.v1.DeleteWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 94, // 129: substrate.ateapi.v1.DeleteWorkerRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 35, // 130: substrate.ateapi.v1.DrainWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 112, // 131: substrate.ateapi.v1.DrainWorkerResponse.worker:type_name -> substrate.ateapi.v1.Worker + 35, // 132: substrate.ateapi.v1.MarkWorkerAvailableRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 112, // 133: substrate.ateapi.v1.MarkWorkerAvailableResponse.worker:type_name -> substrate.ateapi.v1.Worker + 35, // 134: substrate.ateapi.v1.MarkWorkerUnavailableRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 112, // 135: substrate.ateapi.v1.MarkWorkerUnavailableResponse.worker:type_name -> substrate.ateapi.v1.Worker + 95, // 136: substrate.ateapi.v1.ListActorsRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 17, // 137: substrate.ateapi.v1.ListActorsResponse.actors:type_name -> substrate.ateapi.v1.Actor + 14, // 138: substrate.ateapi.v1.Worker.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata + 154, // 139: substrate.ateapi.v1.Worker.labels:type_name -> substrate.ateapi.v1.Worker.LabelsEntry + 113, // 140: substrate.ateapi.v1.Worker.status:type_name -> substrate.ateapi.v1.WorkerStatus + 8, // 141: substrate.ateapi.v1.WorkerStatus.state:type_name -> substrate.ateapi.v1.WorkerState + 120, // 142: substrate.ateapi.v1.WorkerStatus.capacity:type_name -> substrate.ateapi.v1.WorkerResources + 120, // 143: substrate.ateapi.v1.WorkerStatus.allocated:type_name -> substrate.ateapi.v1.WorkerResources + 114, // 144: substrate.ateapi.v1.WorkerStatus.sandbox_classes:type_name -> substrate.ateapi.v1.WorkerSandboxClass + 115, // 145: substrate.ateapi.v1.WorkerSandboxClass.default_runtime:type_name -> substrate.ateapi.v1.WorkerSandboxRuntime + 115, // 146: substrate.ateapi.v1.WorkerSandboxClass.restorable_runtimes:type_name -> substrate.ateapi.v1.WorkerSandboxRuntime + 118, // 147: substrate.ateapi.v1.WorkerSandboxRuntime.version:type_name -> substrate.ateapi.v1.VersionedSandboxCompat + 116, // 148: substrate.ateapi.v1.WorkerSandboxRuntime.actor_overhead:type_name -> substrate.ateapi.v1.RuntimeOverhead + 118, // 149: substrate.ateapi.v1.ActorSandboxRuntime.version:type_name -> substrate.ateapi.v1.VersionedSandboxCompat + 119, // 150: substrate.ateapi.v1.VersionedSandboxCompat.attributes:type_name -> substrate.ateapi.v1.AttributeEntry + 14, // 151: substrate.ateapi.v1.ActorAssignment.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata + 35, // 152: substrate.ateapi.v1.ActorAssignment.actor:type_name -> substrate.ateapi.v1.ObjectRef + 38, // 153: substrate.ateapi.v1.ActorAssignment.resources:type_name -> substrate.ateapi.v1.Resources + 35, // 154: substrate.ateapi.v1.AcquireWorkerEpochRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 155: substrate.ateapi.v1.RegisterWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 120, // 156: substrate.ateapi.v1.RegisterWorkerRequest.capacity:type_name -> substrate.ateapi.v1.WorkerResources + 112, // 157: substrate.ateapi.v1.RegisterWorkerResponse.worker:type_name -> substrate.ateapi.v1.Worker + 35, // 158: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 114, // 159: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest.sandbox_classes:type_name -> substrate.ateapi.v1.WorkerSandboxClass + 112, // 160: substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse.worker:type_name -> substrate.ateapi.v1.Worker + 35, // 161: substrate.ateapi.v1.MintWorkerActorCertificateRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 162: substrate.ateapi.v1.MintWorkerActorCertificateRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 163: substrate.ateapi.v1.MintWorkerActorJwtRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 155, // 164: substrate.ateapi.v1.MintWorkerActorJwtResponse.expire_time:type_name -> google.protobuf.Timestamp + 35, // 165: substrate.ateapi.v1.RequestActorSuspendRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 166: substrate.ateapi.v1.RequestActorSuspendRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 17, // 167: substrate.ateapi.v1.RequestActorSuspendResponse.actor:type_name -> substrate.ateapi.v1.Actor + 35, // 168: substrate.ateapi.v1.ReportActorCrashedRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 169: substrate.ateapi.v1.ReportActorCrashedRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 17, // 170: substrate.ateapi.v1.ReportActorCrashedResponse.actor:type_name -> substrate.ateapi.v1.Actor + 35, // 171: substrate.ateapi.v1.ReportActorSnapshotStateRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 138, // 172: substrate.ateapi.v1.ReportActorSnapshotStateRequest.state:type_name -> substrate.ateapi.v1.ActorSnapshotState + 139, // 173: substrate.ateapi.v1.ActorSnapshotState.latest_local:type_name -> substrate.ateapi.v1.SnapshotReport + 139, // 174: substrate.ateapi.v1.ActorSnapshotState.uploading:type_name -> substrate.ateapi.v1.SnapshotReport + 139, // 175: substrate.ateapi.v1.ActorSnapshotState.latest_durable:type_name -> substrate.ateapi.v1.SnapshotReport + 155, // 176: substrate.ateapi.v1.ActorSnapshotState.upload_due_time:type_name -> google.protobuf.Timestamp + 2, // 177: substrate.ateapi.v1.SnapshotReport.fidelity:type_name -> substrate.ateapi.v1.SnapshotFidelity + 10, // 178: substrate.ateapi.v1.SnapshotReport.object:type_name -> substrate.ateapi.v1.ObjectSnapshot + 155, // 179: substrate.ateapi.v1.SnapshotReport.local_commit_time:type_name -> google.protobuf.Timestamp + 155, // 180: substrate.ateapi.v1.SnapshotReport.durable_complete_time:type_name -> google.protobuf.Timestamp + 14, // 181: substrate.ateapi.v1.AccessPolicy.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata + 141, // 182: substrate.ateapi.v1.AccessPolicy.bindings:type_name -> substrate.ateapi.v1.Binding + 140, // 183: substrate.ateapi.v1.CreateGlobalAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy + 140, // 184: substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy + 35, // 185: substrate.ateapi.v1.GetAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 186: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef + 140, // 187: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy + 35, // 188: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef + 140, // 189: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy + 35, // 190: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef + 94, // 191: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 9, // 192: substrate.ateapi.v1.ResourceAnnotation.scope:type_name -> substrate.ateapi.v1.Scope + 156, // 193: substrate.ateapi.v1.resource:extendee -> google.protobuf.MessageOptions + 157, // 194: substrate.ateapi.v1.method:extendee -> google.protobuf.MethodOptions + 149, // 195: substrate.ateapi.v1.resource:type_name -> substrate.ateapi.v1.ResourceAnnotation + 150, // 196: substrate.ateapi.v1.method:type_name -> substrate.ateapi.v1.MethodAnnotation + 71, // 197: substrate.ateapi.v1.Control.GetActor:input_type -> substrate.ateapi.v1.GetActorRequest + 72, // 198: substrate.ateapi.v1.Control.CreateActor:input_type -> substrate.ateapi.v1.CreateActorRequest + 73, // 199: substrate.ateapi.v1.Control.UpdateActor:input_type -> substrate.ateapi.v1.UpdateActorRequest + 74, // 200: substrate.ateapi.v1.Control.SuspendActor:input_type -> substrate.ateapi.v1.SuspendActorRequest + 77, // 201: substrate.ateapi.v1.Control.ResumeActor:input_type -> substrate.ateapi.v1.ResumeActorRequest + 79, // 202: substrate.ateapi.v1.Control.RevertActor:input_type -> substrate.ateapi.v1.RevertActorRequest + 81, // 203: substrate.ateapi.v1.Control.DeleteActor:input_type -> substrate.ateapi.v1.DeleteActorRequest + 82, // 204: substrate.ateapi.v1.Control.GetActorEgressPolicy:input_type -> substrate.ateapi.v1.GetActorEgressPolicyRequest + 83, // 205: substrate.ateapi.v1.Control.CreateActorEgressPolicy:input_type -> substrate.ateapi.v1.CreateActorEgressPolicyRequest + 84, // 206: substrate.ateapi.v1.Control.UpdateActorEgressPolicy:input_type -> substrate.ateapi.v1.UpdateActorEgressPolicyRequest + 85, // 207: substrate.ateapi.v1.Control.DeleteActorEgressPolicy:input_type -> substrate.ateapi.v1.DeleteActorEgressPolicyRequest + 87, // 208: substrate.ateapi.v1.Control.MintActorJwt:input_type -> substrate.ateapi.v1.MintActorJwtRequest + 91, // 209: substrate.ateapi.v1.Control.CreateTag:input_type -> substrate.ateapi.v1.CreateTagRequest + 86, // 210: substrate.ateapi.v1.Control.GetTag:input_type -> substrate.ateapi.v1.GetTagRequest + 89, // 211: substrate.ateapi.v1.Control.ListTags:input_type -> substrate.ateapi.v1.ListTagsRequest + 92, // 212: substrate.ateapi.v1.Control.UpdateTag:input_type -> substrate.ateapi.v1.UpdateTagRequest + 93, // 213: substrate.ateapi.v1.Control.DeleteTag:input_type -> substrate.ateapi.v1.DeleteTagRequest + 98, // 214: substrate.ateapi.v1.Control.ListWorkers:input_type -> substrate.ateapi.v1.ListWorkersRequest + 100, // 215: substrate.ateapi.v1.Control.GetWorker:input_type -> substrate.ateapi.v1.GetWorkerRequest + 101, // 216: substrate.ateapi.v1.Control.CreateWorker:input_type -> substrate.ateapi.v1.CreateWorkerRequest + 102, // 217: substrate.ateapi.v1.Control.UpdateWorker:input_type -> substrate.ateapi.v1.UpdateWorkerRequest + 103, // 218: substrate.ateapi.v1.Control.DeleteWorker:input_type -> substrate.ateapi.v1.DeleteWorkerRequest + 104, // 219: substrate.ateapi.v1.Control.DrainWorker:input_type -> substrate.ateapi.v1.DrainWorkerRequest + 106, // 220: substrate.ateapi.v1.Control.MarkWorkerAvailable:input_type -> substrate.ateapi.v1.MarkWorkerAvailableRequest + 108, // 221: substrate.ateapi.v1.Control.MarkWorkerUnavailable:input_type -> substrate.ateapi.v1.MarkWorkerUnavailableRequest + 96, // 222: substrate.ateapi.v1.Control.ListWorkerActorAssignments:input_type -> substrate.ateapi.v1.ListWorkerActorAssignmentsRequest + 110, // 223: substrate.ateapi.v1.Control.ListActors:input_type -> substrate.ateapi.v1.ListActorsRequest + 61, // 224: substrate.ateapi.v1.Control.CreateAtespace:input_type -> substrate.ateapi.v1.CreateAtespaceRequest + 62, // 225: substrate.ateapi.v1.Control.GetAtespace:input_type -> substrate.ateapi.v1.GetAtespaceRequest + 63, // 226: substrate.ateapi.v1.Control.ListAtespaces:input_type -> substrate.ateapi.v1.ListAtespacesRequest + 65, // 227: substrate.ateapi.v1.Control.DeleteAtespace:input_type -> substrate.ateapi.v1.DeleteAtespaceRequest + 66, // 228: substrate.ateapi.v1.Control.CreateActorTemplate:input_type -> substrate.ateapi.v1.CreateActorTemplateRequest + 67, // 229: substrate.ateapi.v1.Control.GetActorTemplate:input_type -> substrate.ateapi.v1.GetActorTemplateRequest + 68, // 230: substrate.ateapi.v1.Control.ListActorTemplates:input_type -> substrate.ateapi.v1.ListActorTemplatesRequest + 70, // 231: substrate.ateapi.v1.Control.DeleteActorTemplate:input_type -> substrate.ateapi.v1.DeleteActorTemplateRequest + 142, // 232: substrate.ateapi.v1.Control.GetGlobalAccessPolicy:input_type -> substrate.ateapi.v1.GetGlobalAccessPolicyRequest + 143, // 233: substrate.ateapi.v1.Control.CreateGlobalAccessPolicy:input_type -> substrate.ateapi.v1.CreateGlobalAccessPolicyRequest + 144, // 234: substrate.ateapi.v1.Control.UpdateGlobalAccessPolicy:input_type -> substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest + 145, // 235: substrate.ateapi.v1.Control.GetAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.GetAtespaceAccessPolicyRequest + 146, // 236: substrate.ateapi.v1.Control.CreateAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest + 147, // 237: substrate.ateapi.v1.Control.UpdateAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest + 148, // 238: substrate.ateapi.v1.Control.DeleteAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest + 122, // 239: substrate.ateapi.v1.WorkerService.AcquireWorkerEpoch:input_type -> substrate.ateapi.v1.AcquireWorkerEpochRequest + 124, // 240: substrate.ateapi.v1.WorkerService.RegisterWorker:input_type -> substrate.ateapi.v1.RegisterWorkerRequest + 126, // 241: substrate.ateapi.v1.WorkerService.SetWorkerSandboxRuntimes:input_type -> substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest + 128, // 242: substrate.ateapi.v1.WorkerService.MintWorkerActorCertificate:input_type -> substrate.ateapi.v1.MintWorkerActorCertificateRequest + 130, // 243: substrate.ateapi.v1.WorkerService.MintWorkerActorJwt:input_type -> substrate.ateapi.v1.MintWorkerActorJwtRequest + 132, // 244: substrate.ateapi.v1.WorkerService.RequestActorSuspend:input_type -> substrate.ateapi.v1.RequestActorSuspendRequest + 136, // 245: substrate.ateapi.v1.WorkerService.ReportActorSnapshotState:input_type -> substrate.ateapi.v1.ReportActorSnapshotStateRequest + 134, // 246: substrate.ateapi.v1.WorkerService.ReportActorCrashed:input_type -> substrate.ateapi.v1.ReportActorCrashedRequest + 17, // 247: substrate.ateapi.v1.Control.GetActor:output_type -> substrate.ateapi.v1.Actor + 17, // 248: substrate.ateapi.v1.Control.CreateActor:output_type -> substrate.ateapi.v1.Actor + 17, // 249: substrate.ateapi.v1.Control.UpdateActor:output_type -> substrate.ateapi.v1.Actor + 75, // 250: substrate.ateapi.v1.Control.SuspendActor:output_type -> substrate.ateapi.v1.SuspendActorResponse + 78, // 251: substrate.ateapi.v1.Control.ResumeActor:output_type -> substrate.ateapi.v1.ResumeActorResponse + 80, // 252: substrate.ateapi.v1.Control.RevertActor:output_type -> substrate.ateapi.v1.RevertActorResponse + 17, // 253: substrate.ateapi.v1.Control.DeleteActor:output_type -> substrate.ateapi.v1.Actor + 18, // 254: substrate.ateapi.v1.Control.GetActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy + 18, // 255: substrate.ateapi.v1.Control.CreateActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy + 18, // 256: substrate.ateapi.v1.Control.UpdateActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy + 18, // 257: substrate.ateapi.v1.Control.DeleteActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy + 88, // 258: substrate.ateapi.v1.Control.MintActorJwt:output_type -> substrate.ateapi.v1.MintActorJwtResponse + 33, // 259: substrate.ateapi.v1.Control.CreateTag:output_type -> substrate.ateapi.v1.Tag + 33, // 260: substrate.ateapi.v1.Control.GetTag:output_type -> substrate.ateapi.v1.Tag + 90, // 261: substrate.ateapi.v1.Control.ListTags:output_type -> substrate.ateapi.v1.ListTagsResponse + 33, // 262: substrate.ateapi.v1.Control.UpdateTag:output_type -> substrate.ateapi.v1.Tag + 33, // 263: substrate.ateapi.v1.Control.DeleteTag:output_type -> substrate.ateapi.v1.Tag + 99, // 264: substrate.ateapi.v1.Control.ListWorkers:output_type -> substrate.ateapi.v1.ListWorkersResponse + 112, // 265: substrate.ateapi.v1.Control.GetWorker:output_type -> substrate.ateapi.v1.Worker + 112, // 266: substrate.ateapi.v1.Control.CreateWorker:output_type -> substrate.ateapi.v1.Worker + 112, // 267: substrate.ateapi.v1.Control.UpdateWorker:output_type -> substrate.ateapi.v1.Worker + 112, // 268: substrate.ateapi.v1.Control.DeleteWorker:output_type -> substrate.ateapi.v1.Worker + 105, // 269: substrate.ateapi.v1.Control.DrainWorker:output_type -> substrate.ateapi.v1.DrainWorkerResponse + 107, // 270: substrate.ateapi.v1.Control.MarkWorkerAvailable:output_type -> substrate.ateapi.v1.MarkWorkerAvailableResponse + 109, // 271: substrate.ateapi.v1.Control.MarkWorkerUnavailable:output_type -> substrate.ateapi.v1.MarkWorkerUnavailableResponse + 97, // 272: substrate.ateapi.v1.Control.ListWorkerActorAssignments:output_type -> substrate.ateapi.v1.ListWorkerActorAssignmentsResponse + 111, // 273: substrate.ateapi.v1.Control.ListActors:output_type -> substrate.ateapi.v1.ListActorsResponse + 34, // 274: substrate.ateapi.v1.Control.CreateAtespace:output_type -> substrate.ateapi.v1.Atespace + 34, // 275: substrate.ateapi.v1.Control.GetAtespace:output_type -> substrate.ateapi.v1.Atespace + 64, // 276: substrate.ateapi.v1.Control.ListAtespaces:output_type -> substrate.ateapi.v1.ListAtespacesResponse + 34, // 277: substrate.ateapi.v1.Control.DeleteAtespace:output_type -> substrate.ateapi.v1.Atespace + 36, // 278: substrate.ateapi.v1.Control.CreateActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate + 36, // 279: substrate.ateapi.v1.Control.GetActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate + 69, // 280: substrate.ateapi.v1.Control.ListActorTemplates:output_type -> substrate.ateapi.v1.ListActorTemplatesResponse + 36, // 281: substrate.ateapi.v1.Control.DeleteActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate + 140, // 282: substrate.ateapi.v1.Control.GetGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 140, // 283: substrate.ateapi.v1.Control.CreateGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 140, // 284: substrate.ateapi.v1.Control.UpdateGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 140, // 285: substrate.ateapi.v1.Control.GetAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 140, // 286: substrate.ateapi.v1.Control.CreateAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 140, // 287: substrate.ateapi.v1.Control.UpdateAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 140, // 288: substrate.ateapi.v1.Control.DeleteAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 123, // 289: substrate.ateapi.v1.WorkerService.AcquireWorkerEpoch:output_type -> substrate.ateapi.v1.AcquireWorkerEpochResponse + 125, // 290: substrate.ateapi.v1.WorkerService.RegisterWorker:output_type -> substrate.ateapi.v1.RegisterWorkerResponse + 127, // 291: substrate.ateapi.v1.WorkerService.SetWorkerSandboxRuntimes:output_type -> substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse + 129, // 292: substrate.ateapi.v1.WorkerService.MintWorkerActorCertificate:output_type -> substrate.ateapi.v1.MintWorkerActorCertificateResponse + 131, // 293: substrate.ateapi.v1.WorkerService.MintWorkerActorJwt:output_type -> substrate.ateapi.v1.MintWorkerActorJwtResponse + 133, // 294: substrate.ateapi.v1.WorkerService.RequestActorSuspend:output_type -> substrate.ateapi.v1.RequestActorSuspendResponse + 137, // 295: substrate.ateapi.v1.WorkerService.ReportActorSnapshotState:output_type -> substrate.ateapi.v1.ReportActorSnapshotStateResponse + 135, // 296: substrate.ateapi.v1.WorkerService.ReportActorCrashed:output_type -> substrate.ateapi.v1.ReportActorCrashedResponse + 247, // [247:297] is the sub-list for method output_type + 197, // [197:247] is the sub-list for method input_type + 195, // [195:197] is the sub-list for extension type_name + 193, // [193:195] is the sub-list for extension extendee + 0, // [0:193] is the sub-list for field type_name } func init() { file_api_ateapi_v1_ateapi_proto_init() } @@ -11136,7 +11231,7 @@ func file_api_ateapi_v1_ateapi_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_api_ateapi_v1_ateapi_proto_rawDesc), len(file_api_ateapi_v1_ateapi_proto_rawDesc)), NumEnums: 10, - NumMessages: 143, + NumMessages: 145, NumExtensions: 2, NumServices: 2, }, diff --git a/api/ateapi/v1/ateapi.proto b/api/ateapi/v1/ateapi.proto index 51ed7d1e32..0f1f457a5e 100644 --- a/api/ateapi/v1/ateapi.proto +++ b/api/ateapi/v1/ateapi.proto @@ -1561,6 +1561,40 @@ message ExternalVolumeTemplate { string storage_class_name = 2; } +// ExternalVolumeClass names the CSI driver that provisions external volumes +// and the parameters for its CreateVolume call. Global-scoped and immutable: +// metadata.atespace must be empty. +message ExternalVolumeClass { + option (resource) = { + scope : SCOPE_GLOBAL + plural : "ExternalVolumeClasses" + }; + + // 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 + ResourceMetadata metadata = 1; + + // driver_name is the CSI driver that provisions the volumes, e.g. + // "nfs.csi.k8s.io". It is a DNS subdomain, optionally prefixed with + // "substrate.io/". + // + // +k8s:required + // +k8s:maxLength=63 + // +k8s:customValidation # optional "substrate.io/" prefix + DNS-1123 subdomain + string driver_name = 2; + + // parameters are passed unchanged to the driver's CreateVolume call. The + // driver defines their keys and values, so they are only bounded in size. + // + // +k8s:optional + // +k8s:maxProperties=32 + // +k8s:eachKey=+k8s:maxLength=128 + // +k8s:eachVal=+k8s:maxLength=256 + map parameters = 3; +} + // SystemInfoVolumeSource is a read-only volume of substrate-generated // per-actor files (identity fields, projected trust bundles), regenerated by // atelet on every Run/Restore. diff --git a/tools/apitool/internal/model/model_test.go b/tools/apitool/internal/model/model_test.go index 3e1bbcc25e..8f4c95e6c0 100644 --- a/tools/apitool/internal/model/model_test.go +++ b/tools/apitool/internal/model/model_test.go @@ -237,14 +237,15 @@ func TestBuild_Annotations(t *testing.T) { } } wantResources := map[string]*model.ResourceAnnotation{ - "Actor": {Scope: ateapi.Scope_SCOPE_ATESPACE, Plural: "Actors"}, - "EgressPolicy": {Parents: []string{"Actor"}, Singleton: true, Plural: "EgressPolicies"}, - "Tag": {Scope: ateapi.Scope_SCOPE_ATESPACE, Plural: "Tags"}, - "Atespace": {Scope: ateapi.Scope_SCOPE_GLOBAL, Plural: "Atespaces"}, - "ActorTemplate": {Scope: ateapi.Scope_SCOPE_ATESPACE, Plural: "ActorTemplates"}, - "Worker": {Scope: ateapi.Scope_SCOPE_GLOBAL, Plural: "Workers"}, - "ActorAssignment": {Parents: []string{"Worker"}, Plural: "ActorAssignments"}, - "AccessPolicy": {Parents: []string{"Global", "Atespace"}, Singleton: true, Plural: "AccessPolicies"}, + "Actor": {Scope: ateapi.Scope_SCOPE_ATESPACE, Plural: "Actors"}, + "EgressPolicy": {Parents: []string{"Actor"}, Singleton: true, Plural: "EgressPolicies"}, + "Tag": {Scope: ateapi.Scope_SCOPE_ATESPACE, Plural: "Tags"}, + "Atespace": {Scope: ateapi.Scope_SCOPE_GLOBAL, Plural: "Atespaces"}, + "ActorTemplate": {Scope: ateapi.Scope_SCOPE_ATESPACE, Plural: "ActorTemplates"}, + "ExternalVolumeClass": {Scope: ateapi.Scope_SCOPE_GLOBAL, Plural: "ExternalVolumeClasses"}, + "Worker": {Scope: ateapi.Scope_SCOPE_GLOBAL, Plural: "Workers"}, + "ActorAssignment": {Parents: []string{"Worker"}, Plural: "ActorAssignments"}, + "AccessPolicy": {Parents: []string{"Global", "Atespace"}, Singleton: true, Plural: "AccessPolicies"}, } if diff := cmp.Diff(wantResources, gotResources); diff != "" { t.Errorf("resource annotations mismatch (-want +got):\n%s", diff) From 5fcea160a23640d0c783dfcf613b6ebf3d8d071c Mon Sep 17 00:00:00 2001 From: Vu Le Date: Fri, 6 Nov 2026 23:09:53 +0000 Subject: [PATCH 02/30] add sql migration on store.Interface and atepg.Persistence, unittest, controlapi.ServiceImpl store pass-throughs Signed-off-by: Vu Le --- .../controlapi/external_volume_class.go | 38 +++++ cmd/ateapi/internal/defaults/defaults.go | 4 + cmd/ateapi/internal/defaults/defaults_test.go | 4 + .../store/atepg/external_volume_class.go | 144 ++++++++++++++++++ .../000002_external_volume_classes.sql | 23 +++ cmd/ateapi/internal/store/atepg/pagetoken.go | 2 + cmd/ateapi/internal/store/store.go | 16 ++ 7 files changed, 231 insertions(+) create mode 100644 cmd/ateapi/internal/controlapi/external_volume_class.go create mode 100644 cmd/ateapi/internal/store/atepg/external_volume_class.go create mode 100644 cmd/ateapi/internal/store/atepg/migrations/000002_external_volume_classes.sql diff --git a/cmd/ateapi/internal/controlapi/external_volume_class.go b/cmd/ateapi/internal/controlapi/external_volume_class.go new file mode 100644 index 0000000000..f00a16404a --- /dev/null +++ b/cmd/ateapi/internal/controlapi/external_volume_class.go @@ -0,0 +1,38 @@ +// 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" + + "go.ate.dev/substrate/api/ateapi/v1" + "go.ate.dev/substrate/cmd/ateapi/internal/store" +) + +func (s *ServiceImpl) CreateExternalVolumeClass(ctx context.Context, class *ateapi.ExternalVolumeClass) (*ateapi.ExternalVolumeClass, error) { + return s.store.CreateExternalVolumeClass(ctx, class) +} + +func (s *ServiceImpl) GetExternalVolumeClass(ctx context.Context, name string) (*ateapi.ExternalVolumeClass, error) { + return s.store.GetExternalVolumeClass(ctx, name) +} + +func (s *ServiceImpl) ListExternalVolumeClasses(ctx context.Context, opts store.ListOptions) (store.ListResponse[*ateapi.ExternalVolumeClass], error) { + return s.store.ListExternalVolumeClasses(ctx, opts) +} + +func (s *ServiceImpl) DeleteExternalVolumeClass(ctx context.Context, name string, precondition store.DeletePreconditions) (*ateapi.ExternalVolumeClass, error) { + return s.store.DeleteExternalVolumeClass(ctx, name, precondition) +} diff --git a/cmd/ateapi/internal/defaults/defaults.go b/cmd/ateapi/internal/defaults/defaults.go index 0bffefb536..ebbdcda465 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 *ateapi.EgressPolicy: applyEgressPolicyDefaults(v) + case *ateapi.ExternalVolumeClass: + applyExternalVolumeClassDefaults(v) case *ateapi.Tag: applyTagDefaults(v) case *ateapi.Worker: @@ -117,6 +119,8 @@ func applyEgressRuleDefaults(rules []*ateapi.EgressRule) { } } +func applyExternalVolumeClassDefaults(*ateapi.ExternalVolumeClass) {} + func applyTagDefaults(*ateapi.Tag) {} func applyWorkerDefaults(*ateapi.Worker) {} diff --git a/cmd/ateapi/internal/defaults/defaults_test.go b/cmd/ateapi/internal/defaults/defaults_test.go index 5a1e2e441d..a03e35e439 100644 --- a/cmd/ateapi/internal/defaults/defaults_test.go +++ b/cmd/ateapi/internal/defaults/defaults_test.go @@ -151,6 +151,10 @@ func TestApply(t *testing.T) { {Https: &ateapi.HttpsRule{Hostnames: []string{"custom.example.com"}, Ports: &ateapi.Ports{Numbers: []int32{8443}}}}, {TlsPassthrough: &ateapi.TlsPassthroughRule{Hostnames: []string{"tcp.example.com"}}}, }}}, + }, { + name: "external volume class has no defaults", + in: &ateapi.ExternalVolumeClass{Metadata: &ateapi.ResourceMetadata{Name: "csi-nfs"}, DriverName: "nfs.csi.k8s.io"}, + want: &ateapi.ExternalVolumeClass{Metadata: &ateapi.ResourceMetadata{Name: "csi-nfs"}, DriverName: "nfs.csi.k8s.io"}, }, { name: "tag has no defaults", in: &ateapi.Tag{Scope: ateapi.TagScope_TAG_SCOPE_PUBLISHED}, diff --git a/cmd/ateapi/internal/store/atepg/external_volume_class.go b/cmd/ateapi/internal/store/atepg/external_volume_class.go new file mode 100644 index 0000000000..d7ecb8d3fc --- /dev/null +++ b/cmd/ateapi/internal/store/atepg/external_volume_class.go @@ -0,0 +1,144 @@ +// 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" + + "github.com/jackc/pgx/v5" + "go.ate.dev/substrate/api/ateapi/v1" + "go.ate.dev/substrate/cmd/ateapi/internal/store" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/timestamppb" +) + +func (p *Persistence) CreateExternalVolumeClass(ctx context.Context, class *ateapi.ExternalVolumeClass) (*ateapi.ExternalVolumeClass, error) { + name := class.GetMetadata().GetName() + + dbClass := proto.Clone(class).(*ateapi.ExternalVolumeClass) + setCreateMetadata(dbClass.Metadata) + + protoBytes, err := proto.Marshal(dbClass) + if err != nil { + return nil, fmt.Errorf("marshaling external volume class: %w", err) + } + + _, err = p.pool.Exec(ctx, ` + INSERT INTO external_volume_classes (name, uid, version, proto) + VALUES ($1, $2, $3, $4)`, + name, dbClass.GetMetadata().GetUid(), dbClass.GetMetadata().GetVersion(), protoBytes) + if err != nil { + if isUniqueViolation(err) { + return nil, store.ErrAlreadyExists + } + return nil, fmt.Errorf("inserting external volume class %q: %w", name, err) + } + return dbClass, nil +} + +func (p *Persistence) GetExternalVolumeClass(ctx context.Context, name string) (*ateapi.ExternalVolumeClass, error) { + var protoBytes []byte + err := p.pool.QueryRow(ctx, `SELECT proto FROM external_volume_classes WHERE name = $1`, name).Scan(&protoBytes) + if err != nil { + if errors.Is(err, pgx.ErrNoRows) { + return nil, store.ErrNotFound + } + return nil, fmt.Errorf("getting external volume class %q: %w", name, err) + } + out := &ateapi.ExternalVolumeClass{} + if err := unmarshalStored(protoBytes, out); err != nil { + return nil, fmt.Errorf("unmarshaling external volume class: %w", err) + } + return out, nil +} + +func (p *Persistence) ListExternalVolumeClasses(ctx context.Context, opts store.ListOptions) (store.ListResponse[*ateapi.ExternalVolumeClass], error) { + opts, err := store.NormalizeListOptions(opts) + if err != nil { + return store.ListResponse[*ateapi.ExternalVolumeClass]{}, err + } + pageSize, pageTokenStr := opts.PageSize, opts.PageToken + token, err := decodePageToken(pageTokenStr, kindExternalVolumeClass, "", 1) + if err != nil { + return store.ListResponse[*ateapi.ExternalVolumeClass]{}, err + } + var last *string + if len(token.Last) > 0 { + last = &token.Last[0] + } + + rows, err := p.pool.Query(ctx, ` + SELECT name, proto FROM external_volume_classes + WHERE $1::text IS NULL OR name > $1 + ORDER BY name + LIMIT $2`, last, int64(pageSize)+1) + if err != nil { + return store.ListResponse[*ateapi.ExternalVolumeClass]{}, fmt.Errorf("listing external volume classes: %w", err) + } + defer rows.Close() + + var names []string + var result []*ateapi.ExternalVolumeClass + for rows.Next() { + var name string + var protoBytes []byte + if err := rows.Scan(&name, &protoBytes); err != nil { + return store.ListResponse[*ateapi.ExternalVolumeClass]{}, fmt.Errorf("scanning external volume class row: %w", err) + } + c := &ateapi.ExternalVolumeClass{} + if err := unmarshalRow(protoBytes, c, "external volume class", name); err != nil { + return store.ListResponse[*ateapi.ExternalVolumeClass]{}, err + } + result = append(result, c) + names = append(names, name) + } + if err := rows.Err(); err != nil { + return store.ListResponse[*ateapi.ExternalVolumeClass]{}, fmt.Errorf("listing external volume classes: %w", err) + } + + var nextToken string + if len(result) > int(pageSize) { + result = result[:pageSize] + nextToken = encodePageToken(kindExternalVolumeClass, "", []string{names[pageSize-1]}) + } + return store.ListResponse[*ateapi.ExternalVolumeClass]{Items: result, NextPageToken: nextToken}, nil +} + +func (p *Persistence) DeleteExternalVolumeClass(ctx context.Context, name string, precondition store.DeletePreconditions) (*ateapi.ExternalVolumeClass, error) { + var protoBytes []byte + err := p.pool.QueryRow(ctx, ` + DELETE FROM external_volume_classes + WHERE name = $1 + AND ($2::text = '' OR uid = $2::text) + AND ($3::bigint = 0 OR version = $3::bigint) + RETURNING proto`, 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_volume_classes WHERE name = $1`, name).Scan(&uid, &version) + return nil, mapDeleteError(err, uid, version, precondition) + } + if err != nil { + return nil, fmt.Errorf("deleting external volume class %q: %w", name, err) + } + out := &ateapi.ExternalVolumeClass{} + if err := unmarshalStored(protoBytes, out); err != nil { + return nil, fmt.Errorf("unmarshaling deleted external volume class: %w", err) + } + out.Metadata.DeleteTime = timestamppb.Now() + return out, nil +} diff --git a/cmd/ateapi/internal/store/atepg/migrations/000002_external_volume_classes.sql b/cmd/ateapi/internal/store/atepg/migrations/000002_external_volume_classes.sql new file mode 100644 index 0000000000..b892690a16 --- /dev/null +++ b/cmd/ateapi/internal/store/atepg/migrations/000002_external_volume_classes.sql @@ -0,0 +1,23 @@ +-- 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 + +-- ExternalVolumeClasses are global-scoped, so name alone is the primary key. +CREATE TABLE external_volume_classes ( + name text PRIMARY KEY, + uid text NOT NULL, + version bigint NOT NULL, + proto bytea NOT NULL +); diff --git a/cmd/ateapi/internal/store/atepg/pagetoken.go b/cmd/ateapi/internal/store/atepg/pagetoken.go index 5c8354c229..531167baf1 100644 --- a/cmd/ateapi/internal/store/atepg/pagetoken.go +++ b/cmd/ateapi/internal/store/atepg/pagetoken.go @@ -37,6 +37,8 @@ const ( kindTag resourceKind = "tag" kindWorker resourceKind = "worker" kindWorkerAssign resourceKind = "worker-assignment" + + kindExternalVolumeClass resourceKind = "external-volume-class" ) // pageToken is PostgreSQL's opaque keyset page token. It carries no database diff --git a/cmd/ateapi/internal/store/store.go b/cmd/ateapi/internal/store/store.go index 7545b309e8..e1f743b164 100644 --- a/cmd/ateapi/internal/store/store.go +++ b/cmd/ateapi/internal/store/store.go @@ -217,6 +217,22 @@ type Interface interface { // precondition does not describe the policy the caller observed. DeleteAtespaceAccessPolicy(ctx context.Context, name string, precondition DeletePreconditions) (*ateapi.AccessPolicy, error) + // Stores a new ExternalVolumeClass and returns the stored resource with + // server-assigned metadata (uid, version, timestamps). The input is not + // mutated. Returns ErrAlreadyExists if the name is taken. + CreateExternalVolumeClass(ctx context.Context, class *ateapi.ExternalVolumeClass) (*ateapi.ExternalVolumeClass, error) + + // Fetches an ExternalVolumeClass by name. Returns ErrNotFound if missing. + GetExternalVolumeClass(ctx context.Context, name string) (*ateapi.ExternalVolumeClass, error) + + // Lists ExternalVolumeClasses. + ListExternalVolumeClasses(ctx context.Context, opts ListOptions) (ListResponse[*ateapi.ExternalVolumeClass], error) + + // Removes an ExternalVolumeClass and returns the deleted resource. Returns + // ErrNotFound if missing, or ErrUIDConflict/ErrVersionConflict if + // precondition does not describe the class the caller observed. + DeleteExternalVolumeClass(ctx context.Context, name string, precondition DeletePreconditions) (*ateapi.ExternalVolumeClass, error) + // Stores a new ActorTemplate and returns the stored resource with // server-assigned metadata (uid, version, timestamps). The input is not // mutated. Returns ErrAlreadyExists if the (atespace, name) is taken. From ac15cf933798805be39b4f92504020cb7aa20132 Mon Sep 17 00:00:00 2001 From: Vu Le Date: Fri, 6 Nov 2026 23:11:36 +0000 Subject: [PATCH 03/30] add EVC CRUD, delete precondition, pruning tests, EVC to atepg test table truncation and driver_name column test Signed-off-by: Vu Le --- .../internal/store/atepg/common_test.go | 2 +- .../store/atepg/external_volume_class_test.go | 42 ++++ .../internal/store/storecontract/contract.go | 182 ++++++++++++++++++ 3 files changed, 225 insertions(+), 1 deletion(-) create mode 100644 cmd/ateapi/internal/store/atepg/external_volume_class_test.go diff --git a/cmd/ateapi/internal/store/atepg/common_test.go b/cmd/ateapi/internal/store/atepg/common_test.go index 718317ee30..433ee3659c 100644 --- a/cmd/ateapi/internal/store/atepg/common_test.go +++ b/cmd/ateapi/internal/store/atepg/common_test.go @@ -28,7 +28,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, workers, worker_assignments, leases, worker_outbox, worker_outbox_trim, external_volume_classes, tuple, changelog`); err != nil { t.Fatalf("truncating tables: %v", err) } } diff --git a/cmd/ateapi/internal/store/atepg/external_volume_class_test.go b/cmd/ateapi/internal/store/atepg/external_volume_class_test.go new file mode 100644 index 0000000000..c21b1e6631 --- /dev/null +++ b/cmd/ateapi/internal/store/atepg/external_volume_class_test.go @@ -0,0 +1,42 @@ +// 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" + "testing" + + "go.ate.dev/substrate/api/ateapi/v1" +) + +func TestCreateExternalVolumeClass_StoresDriverName(t *testing.T) { + s := setupPostgresPersistence(t) + ctx := context.Background() + + if _, err := s.CreateExternalVolumeClass(ctx, &ateapi.ExternalVolumeClass{ + Metadata: &ateapi.ResourceMetadata{Name: "nfs"}, + DriverName: "nfs.csi.k8s.io", + }); err != nil { + t.Fatalf("CreateExternalVolumeClass failed: %v", err) + } + + var driverName string + if err := s.pool.QueryRow(ctx, `SELECT driver_name FROM external_volume_classes WHERE name = $1`, "nfs").Scan(&driverName); err != nil { + t.Fatalf("reading driver_name: %v", err) + } + if driverName != "nfs.csi.k8s.io" { + t.Errorf("driver_name column = %q, want %q", driverName, "nfs.csi.k8s.io") + } +} diff --git a/cmd/ateapi/internal/store/storecontract/contract.go b/cmd/ateapi/internal/store/storecontract/contract.go index dc760895fc..c0caea88ee 100644 --- a/cmd/ateapi/internal/store/storecontract/contract.go +++ b/cmd/ateapi/internal/store/storecontract/contract.go @@ -336,6 +336,7 @@ func RunContractTests(t *testing.T, setup func(t *testing.T) store.Interface) { runWorkerContractTests(t, setup) runWorkerAssignmentContractTests(t, setup) runAtespaceContractTests(t, setup) + runExternalVolumeClassContractTests(t, setup) runActorTemplateContractTests(t, setup) runTagContractTests(t, setup) runLeaseContractTests(t, setup) @@ -3513,6 +3514,158 @@ func runAtespaceContractTests(t *testing.T, setup func(t *testing.T) store.Inter }) } +func newTestExternalVolumeClass(name string) *ateapi.ExternalVolumeClass { + return &ateapi.ExternalVolumeClass{ + Metadata: &ateapi.ResourceMetadata{Name: name}, + DriverName: "nfs.csi.k8s.io", + Parameters: map[string]string{"server": "nfs.example.com", "share": "/exports"}, + } +} + +func runExternalVolumeClassContractTests(t *testing.T, setup func(t *testing.T) store.Interface) { + t.Helper() + + t.Run("CreateExternalVolumeClass_Success", func(t *testing.T) { + s := setup(t) + ctx := context.Background() + + want := newTestExternalVolumeClass("nfs") + created, err := s.CreateExternalVolumeClass(ctx, want) + if err != nil { + t.Fatalf("CreateExternalVolumeClass failed: %v", err) + } + if created.GetMetadata().GetUid() == "" { + t.Errorf("CreateExternalVolumeClass returned empty uid; want server-assigned uid") + } + if created.GetMetadata().GetVersion() != 1 { + t.Errorf("CreateExternalVolumeClass returned version %d, want 1", created.GetMetadata().GetVersion()) + } + if diff := cmp.Diff(want, created, protocmp.Transform(), ignoreUID, ignoreTimestamps, ignoreVersion); diff != "" { + t.Errorf("CreateExternalVolumeClass returned unexpected class (-want +got):\n%s", diff) + } + + got, err := s.GetExternalVolumeClass(ctx, "nfs") + if err != nil { + t.Fatalf("GetExternalVolumeClass failed: %v", err) + } + if diff := cmp.Diff(created, got, protocmp.Transform()); diff != "" { + t.Errorf("CreateExternalVolumeClass return does not match stored state (-created +got):\n%s", diff) + } + }) + + t.Run("CreateExternalVolumeClass_AlreadyExists", func(t *testing.T) { + s := setup(t) + ctx := context.Background() + + if _, err := s.CreateExternalVolumeClass(ctx, newTestExternalVolumeClass("nfs")); err != nil { + t.Fatalf("first CreateExternalVolumeClass failed: %v", err) + } + if _, err := s.CreateExternalVolumeClass(ctx, newTestExternalVolumeClass("nfs")); !errors.Is(err, store.ErrAlreadyExists) { + t.Errorf("second CreateExternalVolumeClass = %v, want ErrAlreadyExists", err) + } + }) + + t.Run("GetExternalVolumeClass_NotFound", func(t *testing.T) { + s := setup(t) + + if _, err := s.GetExternalVolumeClass(context.Background(), "nope"); !errors.Is(err, store.ErrNotFound) { + t.Errorf("GetExternalVolumeClass = %v, want ErrNotFound", err) + } + }) + + t.Run("ListExternalVolumeClasses_Pagination", func(t *testing.T) { + s := setup(t) + ctx := context.Background() + + empty, err := s.ListExternalVolumeClasses(ctx, store.ListOptions{PageSize: 1000}) + if err != nil || len(empty.Items) != 0 || empty.NextPageToken != "" { + t.Fatalf("empty ListExternalVolumeClasses = (%v, %q, %v); want empty", empty.Items, empty.NextPageToken, err) + } + + var want []string + for i := range 5 { + name := fmt.Sprintf("class-%d", i) + if _, err := s.CreateExternalVolumeClass(ctx, newTestExternalVolumeClass(name)); err != nil { + t.Fatalf("CreateExternalVolumeClass(%s) failed: %v", name, err) + } + want = append(want, name) + } + + var got []string + pageToken := "" + for { + page, err := s.ListExternalVolumeClasses(ctx, store.ListOptions{PageSize: 2, PageToken: pageToken}) + if err != nil { + t.Fatalf("ListExternalVolumeClasses failed: %v", err) + } + for _, c := range page.Items { + got = append(got, c.GetMetadata().GetName()) + } + pageToken = page.NextPageToken + if pageToken == "" { + break + } + } + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("paged class names mismatch (-want +got):\n%s", diff) + } + }) + + t.Run("DeleteExternalVolumeClass", func(t *testing.T) { + s := setup(t) + ctx := context.Background() + + created, err := s.CreateExternalVolumeClass(ctx, newTestExternalVolumeClass("nfs")) + if err != nil { + t.Fatalf("CreateExternalVolumeClass failed: %v", err) + } + deleted, err := s.DeleteExternalVolumeClass(ctx, "nfs", store.DeletePreconditions{}) + if err != nil { + t.Fatalf("DeleteExternalVolumeClass failed: %v", err) + } + if deleted.GetMetadata().GetDeleteTime() == nil { + t.Error("the deleted class carries no delete_time") + } + if diff := cmp.Diff(created, deleted, protocmp.Transform(), ignoreTimestamps); diff != "" { + t.Errorf("DeleteExternalVolumeClass returned unexpected class (-created +deleted):\n%s", diff) + } + if _, err := s.GetExternalVolumeClass(ctx, "nfs"); !errors.Is(err, store.ErrNotFound) { + t.Errorf("after delete, GetExternalVolumeClass = %v, want ErrNotFound", err) + } + }) + + t.Run("DeleteExternalVolumeClass_Preconditions", func(t *testing.T) { + s := setup(t) + ctx := context.Background() + del := func(precondition store.DeletePreconditions) error { + _, err := s.DeleteExternalVolumeClass(ctx, "nfs", precondition) + return err + } + + if err := del(store.DeletePreconditions{UID: foreignUID, Version: 1}); !errors.Is(err, store.ErrNotFound) { + t.Errorf("guarded delete of a missing class = %v, want ErrNotFound", err) + } + + created, err := s.CreateExternalVolumeClass(ctx, newTestExternalVolumeClass("nfs")) + if err != nil { + t.Fatalf("CreateExternalVolumeClass failed: %v", err) + } + uid, version := created.GetMetadata().GetUid(), created.GetMetadata().GetVersion() + if err := del(store.DeletePreconditions{UID: uid, Version: version + 1}); !errors.Is(err, store.ErrVersionConflict) { + t.Errorf("matching uid, stale version = %v, want ErrVersionConflict", err) + } + if err := del(store.DeletePreconditions{UID: foreignUID, Version: version}); !errors.Is(err, store.ErrUIDConflict) { + t.Errorf("foreign uid, matching version = %v, want ErrUIDConflict", err) + } + if _, err := s.GetExternalVolumeClass(ctx, "nfs"); err != nil { + t.Fatalf("a refused delete removed the class: %v", err) + } + if err := del(store.DeletePreconditions{UID: uid, Version: version}); err != nil { + t.Errorf("matching uid and version = %v, want nil", err) + } + }) +} + func runLeaseContractTests(t *testing.T, setup func(t *testing.T) store.Interface) { t.Helper() @@ -3760,6 +3913,35 @@ func runUnknownFieldContractTests(t *testing.T, setup func(t *testing.T) store.I assertPruned(t, "DeleteAtespace", created, deleted) }) + t.Run("UnknownFields_ExternalVolumeClass", func(t *testing.T) { + s := setup(t) + ctx := context.Background() + class := withUnknownField(newTestExternalVolumeClass("nfs")) + withUnknownField(class.Metadata) + created, err := s.CreateExternalVolumeClass(ctx, class) + if err != nil { + t.Fatalf("CreateExternalVolumeClass failed: %v", err) + } + + got, err := s.GetExternalVolumeClass(ctx, "nfs") + if err != nil { + t.Fatalf("GetExternalVolumeClass failed: %v", err) + } + assertPruned(t, "GetExternalVolumeClass", created, got) + + list, err := s.ListExternalVolumeClasses(ctx, store.ListOptions{}) + if err != nil || len(list.Items) != 1 { + t.Fatalf("ListExternalVolumeClasses = %d items, %v; want 1", len(list.Items), err) + } + assertPruned(t, "ListExternalVolumeClasses", created, list.Items[0]) + + deleted, err := s.DeleteExternalVolumeClass(ctx, "nfs", store.DeletePreconditions{}) + if err != nil { + t.Fatalf("DeleteExternalVolumeClass failed: %v", err) + } + assertPruned(t, "DeleteExternalVolumeClass", created, deleted) + }) + t.Run("UnknownFields_ActorTemplate", func(t *testing.T) { s := setup(t) ctx := context.Background() From 60152eead99d7fbc143484cad8d61ffde2965c8e Mon Sep 17 00:00:00 2001 From: Vu Le Date: Mon, 9 Nov 2026 19:47:33 +0000 Subject: [PATCH 04/30] add Substrate Authors headers Signed-off-by: Vu Le --- .../controlapi/external_volume_class.go | 2 +- .../store/atepg/external_volume_class.go | 2 +- .../store/atepg/external_volume_class_test.go | 42 ------------------- .../000002_external_volume_classes.sql | 2 +- 4 files changed, 3 insertions(+), 45 deletions(-) delete mode 100644 cmd/ateapi/internal/store/atepg/external_volume_class_test.go diff --git a/cmd/ateapi/internal/controlapi/external_volume_class.go b/cmd/ateapi/internal/controlapi/external_volume_class.go index f00a16404a..68c25dafd6 100644 --- a/cmd/ateapi/internal/controlapi/external_volume_class.go +++ b/cmd/ateapi/internal/controlapi/external_volume_class.go @@ -1,4 +1,4 @@ -// Copyright 2026 Google LLC +// Copyright 2026 The Agent Substrate Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/cmd/ateapi/internal/store/atepg/external_volume_class.go b/cmd/ateapi/internal/store/atepg/external_volume_class.go index d7ecb8d3fc..66f2cf4b8a 100644 --- a/cmd/ateapi/internal/store/atepg/external_volume_class.go +++ b/cmd/ateapi/internal/store/atepg/external_volume_class.go @@ -1,4 +1,4 @@ -// Copyright 2026 Google LLC +// Copyright 2026 The Agent Substrate Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/cmd/ateapi/internal/store/atepg/external_volume_class_test.go b/cmd/ateapi/internal/store/atepg/external_volume_class_test.go deleted file mode 100644 index c21b1e6631..0000000000 --- a/cmd/ateapi/internal/store/atepg/external_volume_class_test.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package atepg - -import ( - "context" - "testing" - - "go.ate.dev/substrate/api/ateapi/v1" -) - -func TestCreateExternalVolumeClass_StoresDriverName(t *testing.T) { - s := setupPostgresPersistence(t) - ctx := context.Background() - - if _, err := s.CreateExternalVolumeClass(ctx, &ateapi.ExternalVolumeClass{ - Metadata: &ateapi.ResourceMetadata{Name: "nfs"}, - DriverName: "nfs.csi.k8s.io", - }); err != nil { - t.Fatalf("CreateExternalVolumeClass failed: %v", err) - } - - var driverName string - if err := s.pool.QueryRow(ctx, `SELECT driver_name FROM external_volume_classes WHERE name = $1`, "nfs").Scan(&driverName); err != nil { - t.Fatalf("reading driver_name: %v", err) - } - if driverName != "nfs.csi.k8s.io" { - t.Errorf("driver_name column = %q, want %q", driverName, "nfs.csi.k8s.io") - } -} diff --git a/cmd/ateapi/internal/store/atepg/migrations/000002_external_volume_classes.sql b/cmd/ateapi/internal/store/atepg/migrations/000002_external_volume_classes.sql index b892690a16..cfceb9c182 100644 --- a/cmd/ateapi/internal/store/atepg/migrations/000002_external_volume_classes.sql +++ b/cmd/ateapi/internal/store/atepg/migrations/000002_external_volume_classes.sql @@ -1,4 +1,4 @@ --- Copyright 2026 Google LLC +-- Copyright 2026 The Agent Substrate Authors -- -- Licensed under the Apache License, Version 2.0 (the "License"); -- you may not use this file except in compliance with the License. From 722a190e4ebc232f297df50e4d78269b99e59b91 Mon Sep 17 00:00:00 2001 From: Vu Le Date: Mon, 9 Nov 2026 18:59:47 +0000 Subject: [PATCH 05/30] openFGA model, contextual tuples and authz helpers Signed-off-by: Vu Le --- cmd/ateapi/internal/authz/authorizer.go | 27 ++++++------- cmd/ateapi/internal/authz/authorizer_test.go | 5 +++ cmd/ateapi/internal/authz/authz_util.go | 9 +++++ cmd/ateapi/internal/authz/model.fga | 12 ++++++ cmd/ateapi/internal/authz/model_test.fga.yaml | 38 +++++++++++++++++++ 5 files changed, 78 insertions(+), 13 deletions(-) diff --git a/cmd/ateapi/internal/authz/authorizer.go b/cmd/ateapi/internal/authz/authorizer.go index dac3a324f0..1b6aed763d 100644 --- a/cmd/ateapi/internal/authz/authorizer.go +++ b/cmd/ateapi/internal/authz/authorizer.go @@ -52,9 +52,9 @@ type Authorizer struct { } // Check verifies that the principal in ctx has relation on object. -// Structural hierarchy links (global:root as parent_global of every atespace -// and worker, and each atespace as parent_atespace of its actors, actor -// templates and tags) and +// Structural hierarchy links (global:root as parent_global of every atespace, +// worker and external volume class, and each atespace as parent_atespace of +// its actors, actor templates and tags) and // the caller's bootstrap owner and system role grants, if any, are injected as OpenFGA // ContextualTuples at evaluation time rather than persisted in the tuple table. func (a *Authorizer) Check(ctx context.Context, relation, object string) error { @@ -129,20 +129,21 @@ func (a *Authorizer) checkRaw(ctx context.Context, user, relation, object string // tuples in PostgreSQL. // // Why contextual tuples are used instead of storing parent links in the database: -// 1. Deterministic structure: Every `atespace:` and `worker:` -// unconditionally has `global:root` as its `parent_global`, and every -// `actor:/`, `actor_template:/` and -// `tag:/` has `atespace:` as its -// `parent_atespace`. Because these +// 1. Deterministic structure: Every `atespace:`, `worker:` and +// `external_volume_class:` unconditionally has `global:root` as its +// `parent_global`, and every `actor:/`, +// `actor_template:/` and `tag:/` has +// `atespace:` as its `parent_atespace`. Because these // relationships are derived purely from the object type/ID, storing a row // per resource in the OpenFGA `tuple` table would be redundant. // 2. No write amplification on create: `CreateAtespace`, `CreateWorker`, -// `CreateActorTemplate`, `CreateActor` and `CreateTag` can insert their rows without -// opening an OpenFGA write transaction just to link the parent. +// `CreateExternalVolumeClass`, `CreateActorTemplate`, `CreateActor` and +// `CreateTag` can insert their rows without opening an OpenFGA write +// transaction just to link the parent. func contextualTuples(object string) []*openfgav1.TupleKey { objectType, id, _ := strings.Cut(object, ":") switch objectType { - case "atespace", "worker": + case "atespace", "worker", "external_volume_class": return []*openfgav1.TupleKey{parentGlobalTuple(object)} case "actor", "actor_template", "tag": atespace, _, ok := strings.Cut(id, "/") @@ -159,8 +160,8 @@ func contextualTuples(object string) []*openfgav1.TupleKey { return nil } -// parentGlobalTuple links a global-scoped object (an atespace or a worker) to -// global:root. +// parentGlobalTuple links a global-scoped object (an atespace, a worker or an +// external volume class) to global:root. func parentGlobalTuple(object string) *openfgav1.TupleKey { return &openfgav1.TupleKey{ User: GlobalRootObject, diff --git a/cmd/ateapi/internal/authz/authorizer_test.go b/cmd/ateapi/internal/authz/authorizer_test.go index c35b7179e0..4fb5b40d3e 100644 --- a/cmd/ateapi/internal/authz/authorizer_test.go +++ b/cmd/ateapi/internal/authz/authorizer_test.go @@ -50,6 +50,11 @@ func TestContextualTuples(t *testing.T) { object: WorkerObject("w-1"), want: []*openfgav1.TupleKey{parentGlobal("worker:w-1")}, }, + { + name: "external volume class", + object: ExternalVolumeClassObject("nfs-gold"), + want: []*openfgav1.TupleKey{parentGlobal("external_volume_class:nfs-gold")}, + }, { name: "actor", object: ActorObject("team-a", "runner"), diff --git a/cmd/ateapi/internal/authz/authz_util.go b/cmd/ateapi/internal/authz/authz_util.go index 092beb80fd..93f6e62088 100644 --- a/cmd/ateapi/internal/authz/authz_util.go +++ b/cmd/ateapi/internal/authz/authz_util.go @@ -80,6 +80,9 @@ const ( RelationCanUseTag = "can_use_tag" RelationCanMintActorJWT = "can_mint_actor_jwt" + RelationCanCreateExternalVolumeClass = "can_create_external_volume_class" + RelationCanListExternalVolumeClasses = "can_list_external_volume_classes" + // maxTuplesPerWrite is OpenFGA's default maximum number of tuples allowed in a single Write request. maxTuplesPerWrite = 100 ) @@ -128,6 +131,12 @@ func WorkerObject(name string) string { return "worker:" + objectIDReplacer.Replace(name) } +// ExternalVolumeClassObject formats an external volume class name as an +// OpenFGA object string. External volume classes are global-scoped. +func ExternalVolumeClassObject(name string) string { + return "external_volume_class:" + objectIDReplacer.Replace(name) +} + // ActorObject formats an actor as an OpenFGA object string. func ActorObject(atespace, name string) string { return "actor:" + atespacedID(atespace, name) diff --git a/cmd/ateapi/internal/authz/model.fga b/cmd/ateapi/internal/authz/model.fga index bf689b48e0..e450b762db 100644 --- a/cmd/ateapi/internal/authz/model.fga +++ b/cmd/ateapi/internal/authz/model.fga @@ -65,11 +65,23 @@ type global define can_list_actor_templates: viewer define can_list_tags: viewer + # --- Volume Infrastructure --- + define can_create_external_volume_class: owner + define can_list_external_volume_classes: viewer + # --- Policy Governance --- define can_create_access_policy: owner define can_get_access_policy: viewer define can_update_access_policy: owner +# Global-scoped; inherits its roles from global. +type external_volume_class + relations + define parent_global: [global] + + define can_get: viewer from parent_global + define can_delete: owner from parent_global + type atespace relations define parent_global: [global] diff --git a/cmd/ateapi/internal/authz/model_test.fga.yaml b/cmd/ateapi/internal/authz/model_test.fga.yaml index c9cb9916ce..c0806f9e91 100644 --- a/cmd/ateapi/internal/authz/model_test.fga.yaml +++ b/cmd/ateapi/internal/authz/model_test.fga.yaml @@ -94,6 +94,11 @@ tuples: relation: api_server_sidecar object: global:root + # External volume class (nfs-gold linked to global:root) + - user: global:root + relation: parent_global + object: external_volume_class:nfs-gold + tests: - name: 1. Global Superadmin & Viewer Propagation check: @@ -572,3 +577,36 @@ tests: object: actor:runner-1 assertions: can_mint_actor_jwt: false + + - name: 10. External Volume Classes (Inherited from Global) + check: + - user: user:carol # Global owner + object: global:root + assertions: + can_create_external_volume_class: true + can_list_external_volume_classes: true + - user: user:frank # Global viewer + object: global:root + assertions: + can_create_external_volume_class: false + can_list_external_volume_classes: true + - user: user:bob # Atespace editor + object: global:root + assertions: + can_create_external_volume_class: false + can_list_external_volume_classes: false + - user: user:carol + object: external_volume_class:nfs-gold + assertions: + can_get: true + can_delete: true + - user: user:frank + object: external_volume_class:nfs-gold + assertions: + can_get: true + can_delete: false + - user: user:bob + object: external_volume_class:nfs-gold + assertions: + can_get: false + can_delete: false From 5f005db53b66b22019316195a4bc6454b3b9988d Mon Sep 17 00:00:00 2001 From: Vu Le Date: Mon, 9 Nov 2026 19:01:06 +0000 Subject: [PATCH 06/30] ExternalVolumeClass CRUD RPCs, validation, RPC permission registry and apitool example Signed-off-by: Vu Le --- api/ateapi/v1/ateapi.pb.go | 1462 ++++++++++------- api/ateapi/v1/ateapi.proto | 73 + api/ateapi/v1/ateapi_grpc.pb.go | 164 ++ .../apivalidation/external_volume_class.go | 44 + .../external_volume_class_test.go | 135 ++ .../apivalidation/zz_generated.validation.go | 377 +++++ cmd/ateapi/internal/authz/registry.go | 21 + cmd/ateapi/internal/authz/registry_test.go | 38 + .../examples/grpc/ExternalVolumeClass.yaml | 23 + 9 files changed, 1757 insertions(+), 580 deletions(-) create mode 100644 cmd/ateapi/internal/apivalidation/external_volume_class.go create mode 100644 cmd/ateapi/internal/apivalidation/external_volume_class_test.go create mode 100644 tools/apitool/internal/examples/grpc/ExternalVolumeClass.yaml diff --git a/api/ateapi/v1/ateapi.pb.go b/api/ateapi/v1/ateapi.pb.go index a6a774b771..9228052ceb 100644 --- a/api/ateapi/v1/ateapi.pb.go +++ b/api/ateapi/v1/ateapi.pb.go @@ -4753,6 +4753,269 @@ func (x *DeleteAtespaceRequest) GetOptions() *DeleteOptions { return nil } +// CreateExternalVolumeClassRequest creates an ExternalVolumeClass. +type CreateExternalVolumeClassRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The class to create. metadata.name is required and metadata.atespace + // must be empty. + // + // +ate:preview=ExternalVolumes + // +k8s:ifDisabled(ExternalVolumes)=+k8s:forbidden + // +k8s:required + ExternalVolumeClass *ExternalVolumeClass `protobuf:"bytes,1,opt,name=external_volume_class,json=externalVolumeClass,proto3" json:"external_volume_class,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateExternalVolumeClassRequest) Reset() { + *x = CreateExternalVolumeClassRequest{} + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[56] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateExternalVolumeClassRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateExternalVolumeClassRequest) ProtoMessage() {} + +func (x *CreateExternalVolumeClassRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[56] + 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 CreateExternalVolumeClassRequest.ProtoReflect.Descriptor instead. +func (*CreateExternalVolumeClassRequest) Descriptor() ([]byte, []int) { + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{56} +} + +func (x *CreateExternalVolumeClassRequest) GetExternalVolumeClass() *ExternalVolumeClass { + if x != nil { + return x.ExternalVolumeClass + } + return nil +} + +// GetExternalVolumeClassRequest identifies the ExternalVolumeClass to get. +type GetExternalVolumeClassRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The class to get. atespace must be empty. + // + // +k8s:required + // +k8s:beta(since: "0.0")=+k8s:subfield(atespace)=+k8s:forbidden # TODO: get rid of beta prefix + ExternalVolumeClass *ObjectRef `protobuf:"bytes,1,opt,name=external_volume_class,json=externalVolumeClass,proto3" json:"external_volume_class,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetExternalVolumeClassRequest) Reset() { + *x = GetExternalVolumeClassRequest{} + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[57] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetExternalVolumeClassRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetExternalVolumeClassRequest) ProtoMessage() {} + +func (x *GetExternalVolumeClassRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[57] + 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 GetExternalVolumeClassRequest.ProtoReflect.Descriptor instead. +func (*GetExternalVolumeClassRequest) Descriptor() ([]byte, []int) { + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{57} +} + +func (x *GetExternalVolumeClassRequest) GetExternalVolumeClass() *ObjectRef { + if x != nil { + return x.ExternalVolumeClass + } + return nil +} + +// ListExternalVolumeClassesRequest asks for a page of ExternalVolumeClasses. +type ListExternalVolumeClassesRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Pagination controls. + // + // +k8s:optional + Options *ListOptions `protobuf:"bytes,1,opt,name=options,proto3" json:"options,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListExternalVolumeClassesRequest) Reset() { + *x = ListExternalVolumeClassesRequest{} + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[58] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListExternalVolumeClassesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListExternalVolumeClassesRequest) ProtoMessage() {} + +func (x *ListExternalVolumeClassesRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[58] + 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 ListExternalVolumeClassesRequest.ProtoReflect.Descriptor instead. +func (*ListExternalVolumeClassesRequest) Descriptor() ([]byte, []int) { + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{58} +} + +func (x *ListExternalVolumeClassesRequest) GetOptions() *ListOptions { + if x != nil { + return x.Options + } + return nil +} + +// ListExternalVolumeClassesResponse is one page of ExternalVolumeClasses. +type ListExternalVolumeClassesResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The page of classes. This list may be empty even if there are more results. + ExternalVolumeClasses []*ExternalVolumeClass `protobuf:"bytes,1,rep,name=external_volume_classes,json=externalVolumeClasses,proto3" json:"external_volume_classes,omitempty"` + // Pagination token for the next page. Empty if this is 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 *ListExternalVolumeClassesResponse) Reset() { + *x = ListExternalVolumeClassesResponse{} + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[59] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListExternalVolumeClassesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListExternalVolumeClassesResponse) ProtoMessage() {} + +func (x *ListExternalVolumeClassesResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[59] + 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 ListExternalVolumeClassesResponse.ProtoReflect.Descriptor instead. +func (*ListExternalVolumeClassesResponse) Descriptor() ([]byte, []int) { + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{59} +} + +func (x *ListExternalVolumeClassesResponse) GetExternalVolumeClasses() []*ExternalVolumeClass { + if x != nil { + return x.ExternalVolumeClasses + } + return nil +} + +func (x *ListExternalVolumeClassesResponse) GetNextPageToken() string { + if x != nil { + return x.NextPageToken + } + return "" +} + +// DeleteExternalVolumeClassRequest identifies the ExternalVolumeClass to delete. +type DeleteExternalVolumeClassRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The class to delete. atespace must be empty. + // + // +k8s:required + // +k8s:beta(since: "0.0")=+k8s:subfield(atespace)=+k8s:forbidden # TODO: get rid of beta prefix + ExternalVolumeClass *ObjectRef `protobuf:"bytes,1,opt,name=external_volume_class,json=externalVolumeClass,proto3" json:"external_volume_class,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 *DeleteExternalVolumeClassRequest) Reset() { + *x = DeleteExternalVolumeClassRequest{} + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[60] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteExternalVolumeClassRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteExternalVolumeClassRequest) ProtoMessage() {} + +func (x *DeleteExternalVolumeClassRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[60] + 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 DeleteExternalVolumeClassRequest.ProtoReflect.Descriptor instead. +func (*DeleteExternalVolumeClassRequest) Descriptor() ([]byte, []int) { + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{60} +} + +func (x *DeleteExternalVolumeClassRequest) GetExternalVolumeClass() *ObjectRef { + if x != nil { + return x.ExternalVolumeClass + } + return nil +} + +func (x *DeleteExternalVolumeClassRequest) GetOptions() *DeleteOptions { + if x != nil { + return x.Options + } + return nil +} + type CreateActorTemplateRequest struct { state protoimpl.MessageState `protogen:"open.v1"` // The actor template version to create. Server-assigned metadata (uid, @@ -4767,7 +5030,7 @@ type CreateActorTemplateRequest struct { func (x *CreateActorTemplateRequest) Reset() { *x = CreateActorTemplateRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[56] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4779,7 +5042,7 @@ func (x *CreateActorTemplateRequest) String() string { func (*CreateActorTemplateRequest) ProtoMessage() {} func (x *CreateActorTemplateRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[56] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[61] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4792,7 +5055,7 @@ func (x *CreateActorTemplateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateActorTemplateRequest.ProtoReflect.Descriptor instead. func (*CreateActorTemplateRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{56} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{61} } func (x *CreateActorTemplateRequest) GetActorTemplate() *ActorTemplate { @@ -4813,7 +5076,7 @@ type GetActorTemplateRequest struct { func (x *GetActorTemplateRequest) Reset() { *x = GetActorTemplateRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[57] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4825,7 +5088,7 @@ func (x *GetActorTemplateRequest) String() string { func (*GetActorTemplateRequest) ProtoMessage() {} func (x *GetActorTemplateRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[57] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[62] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4838,7 +5101,7 @@ func (x *GetActorTemplateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetActorTemplateRequest.ProtoReflect.Descriptor instead. func (*GetActorTemplateRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{57} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{62} } func (x *GetActorTemplateRequest) GetActorTemplate() *ObjectRef { @@ -4866,7 +5129,7 @@ type ListActorTemplatesRequest struct { func (x *ListActorTemplatesRequest) Reset() { *x = ListActorTemplatesRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[58] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4878,7 +5141,7 @@ func (x *ListActorTemplatesRequest) String() string { func (*ListActorTemplatesRequest) ProtoMessage() {} func (x *ListActorTemplatesRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[58] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[63] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4891,7 +5154,7 @@ func (x *ListActorTemplatesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListActorTemplatesRequest.ProtoReflect.Descriptor instead. func (*ListActorTemplatesRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{58} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{63} } func (x *ListActorTemplatesRequest) GetAtespace() string { @@ -4921,7 +5184,7 @@ type ListActorTemplatesResponse struct { func (x *ListActorTemplatesResponse) Reset() { *x = ListActorTemplatesResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[59] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4933,7 +5196,7 @@ func (x *ListActorTemplatesResponse) String() string { func (*ListActorTemplatesResponse) ProtoMessage() {} func (x *ListActorTemplatesResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[59] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[64] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4946,7 +5209,7 @@ func (x *ListActorTemplatesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListActorTemplatesResponse.ProtoReflect.Descriptor instead. func (*ListActorTemplatesResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{59} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{64} } func (x *ListActorTemplatesResponse) GetActorTemplates() []*ActorTemplate { @@ -4978,7 +5241,7 @@ type DeleteActorTemplateRequest struct { func (x *DeleteActorTemplateRequest) Reset() { *x = DeleteActorTemplateRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[60] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4990,7 +5253,7 @@ func (x *DeleteActorTemplateRequest) String() string { func (*DeleteActorTemplateRequest) ProtoMessage() {} func (x *DeleteActorTemplateRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[60] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[65] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5003,7 +5266,7 @@ func (x *DeleteActorTemplateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteActorTemplateRequest.ProtoReflect.Descriptor instead. func (*DeleteActorTemplateRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{60} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{65} } func (x *DeleteActorTemplateRequest) GetActorTemplate() *ObjectRef { @@ -5031,7 +5294,7 @@ type GetActorRequest struct { func (x *GetActorRequest) Reset() { *x = GetActorRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[61] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5043,7 +5306,7 @@ func (x *GetActorRequest) String() string { func (*GetActorRequest) ProtoMessage() {} func (x *GetActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[61] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[66] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5056,7 +5319,7 @@ func (x *GetActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetActorRequest.ProtoReflect.Descriptor instead. func (*GetActorRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{61} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{66} } func (x *GetActorRequest) GetActor() *ObjectRef { @@ -5079,7 +5342,7 @@ type CreateActorRequest struct { func (x *CreateActorRequest) Reset() { *x = CreateActorRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[62] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5091,7 +5354,7 @@ func (x *CreateActorRequest) String() string { func (*CreateActorRequest) ProtoMessage() {} func (x *CreateActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[62] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[67] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5104,7 +5367,7 @@ func (x *CreateActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateActorRequest.ProtoReflect.Descriptor instead. func (*CreateActorRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{62} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{67} } func (x *CreateActorRequest) GetActor() *Actor { @@ -5135,7 +5398,7 @@ type UpdateActorRequest struct { func (x *UpdateActorRequest) Reset() { *x = UpdateActorRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[63] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5147,7 +5410,7 @@ func (x *UpdateActorRequest) String() string { func (*UpdateActorRequest) ProtoMessage() {} func (x *UpdateActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[63] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[68] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5160,7 +5423,7 @@ func (x *UpdateActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateActorRequest.ProtoReflect.Descriptor instead. func (*UpdateActorRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{63} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{68} } func (x *UpdateActorRequest) GetActor() *Actor { @@ -5185,7 +5448,7 @@ type SuspendActorRequest struct { func (x *SuspendActorRequest) Reset() { *x = SuspendActorRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[64] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5197,7 +5460,7 @@ func (x *SuspendActorRequest) String() string { func (*SuspendActorRequest) ProtoMessage() {} func (x *SuspendActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[64] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[69] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5210,7 +5473,7 @@ func (x *SuspendActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SuspendActorRequest.ProtoReflect.Descriptor instead. func (*SuspendActorRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{64} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{69} } func (x *SuspendActorRequest) GetActor() *ObjectRef { @@ -5236,7 +5499,7 @@ type SuspendActorResponse struct { func (x *SuspendActorResponse) Reset() { *x = SuspendActorResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[65] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5248,7 +5511,7 @@ func (x *SuspendActorResponse) String() string { func (*SuspendActorResponse) ProtoMessage() {} func (x *SuspendActorResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[65] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[70] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5261,7 +5524,7 @@ func (x *SuspendActorResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SuspendActorResponse.ProtoReflect.Descriptor instead. func (*SuspendActorResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{65} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{70} } func (x *SuspendActorResponse) GetActor() *Actor { @@ -5287,7 +5550,7 @@ type SuspendOptions struct { func (x *SuspendOptions) Reset() { *x = SuspendOptions{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[66] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5299,7 +5562,7 @@ func (x *SuspendOptions) String() string { func (*SuspendOptions) ProtoMessage() {} func (x *SuspendOptions) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[66] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[71] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5312,7 +5575,7 @@ func (x *SuspendOptions) ProtoReflect() protoreflect.Message { // Deprecated: Use SuspendOptions.ProtoReflect.Descriptor instead. func (*SuspendOptions) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{66} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{71} } func (x *SuspendOptions) GetMode() DurabilityMode { @@ -5333,7 +5596,7 @@ type ResumeActorRequest struct { func (x *ResumeActorRequest) Reset() { *x = ResumeActorRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[67] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5345,7 +5608,7 @@ func (x *ResumeActorRequest) String() string { func (*ResumeActorRequest) ProtoMessage() {} func (x *ResumeActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[67] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[72] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5358,7 +5621,7 @@ func (x *ResumeActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ResumeActorRequest.ProtoReflect.Descriptor instead. func (*ResumeActorRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{67} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{72} } func (x *ResumeActorRequest) GetActor() *ObjectRef { @@ -5380,7 +5643,7 @@ type ResumeActorResponse struct { func (x *ResumeActorResponse) Reset() { *x = ResumeActorResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[68] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5392,7 +5655,7 @@ func (x *ResumeActorResponse) String() string { func (*ResumeActorResponse) ProtoMessage() {} func (x *ResumeActorResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[68] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[73] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5405,7 +5668,7 @@ func (x *ResumeActorResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ResumeActorResponse.ProtoReflect.Descriptor instead. func (*ResumeActorResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{68} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{73} } func (x *ResumeActorResponse) GetActor() *Actor { @@ -5435,7 +5698,7 @@ type RevertActorRequest struct { func (x *RevertActorRequest) Reset() { *x = RevertActorRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[69] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5447,7 +5710,7 @@ func (x *RevertActorRequest) String() string { func (*RevertActorRequest) ProtoMessage() {} func (x *RevertActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[69] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[74] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5460,7 +5723,7 @@ func (x *RevertActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RevertActorRequest.ProtoReflect.Descriptor instead. func (*RevertActorRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{69} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{74} } func (x *RevertActorRequest) GetActor() *ObjectRef { @@ -5482,7 +5745,7 @@ type RevertActorResponse struct { func (x *RevertActorResponse) Reset() { *x = RevertActorResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[70] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5494,7 +5757,7 @@ func (x *RevertActorResponse) String() string { func (*RevertActorResponse) ProtoMessage() {} func (x *RevertActorResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[70] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[75] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5507,7 +5770,7 @@ func (x *RevertActorResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RevertActorResponse.ProtoReflect.Descriptor instead. func (*RevertActorResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{70} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{75} } func (x *RevertActorResponse) GetActor() *Actor { @@ -5532,7 +5795,7 @@ type DeleteActorRequest struct { func (x *DeleteActorRequest) Reset() { *x = DeleteActorRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[71] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5544,7 +5807,7 @@ func (x *DeleteActorRequest) String() string { func (*DeleteActorRequest) ProtoMessage() {} func (x *DeleteActorRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[71] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[76] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5557,7 +5820,7 @@ func (x *DeleteActorRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteActorRequest.ProtoReflect.Descriptor instead. func (*DeleteActorRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{71} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{76} } func (x *DeleteActorRequest) GetActor() *ObjectRef { @@ -5594,7 +5857,7 @@ type GetActorEgressPolicyRequest struct { func (x *GetActorEgressPolicyRequest) Reset() { *x = GetActorEgressPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[72] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5606,7 +5869,7 @@ func (x *GetActorEgressPolicyRequest) String() string { func (*GetActorEgressPolicyRequest) ProtoMessage() {} func (x *GetActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[72] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[77] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5619,7 +5882,7 @@ func (x *GetActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetActorEgressPolicyRequest.ProtoReflect.Descriptor instead. func (*GetActorEgressPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{72} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{77} } func (x *GetActorEgressPolicyRequest) GetActor() *ObjectRef { @@ -5657,7 +5920,7 @@ type CreateActorEgressPolicyRequest struct { func (x *CreateActorEgressPolicyRequest) Reset() { *x = CreateActorEgressPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[73] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5669,7 +5932,7 @@ func (x *CreateActorEgressPolicyRequest) String() string { func (*CreateActorEgressPolicyRequest) ProtoMessage() {} func (x *CreateActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[73] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[78] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5682,7 +5945,7 @@ func (x *CreateActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateActorEgressPolicyRequest.ProtoReflect.Descriptor instead. func (*CreateActorEgressPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{73} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{78} } func (x *CreateActorEgressPolicyRequest) GetActor() *ObjectRef { @@ -5720,7 +5983,7 @@ type UpdateActorEgressPolicyRequest struct { func (x *UpdateActorEgressPolicyRequest) Reset() { *x = UpdateActorEgressPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[74] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5732,7 +5995,7 @@ func (x *UpdateActorEgressPolicyRequest) String() string { func (*UpdateActorEgressPolicyRequest) ProtoMessage() {} func (x *UpdateActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[74] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[79] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5745,7 +6008,7 @@ func (x *UpdateActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateActorEgressPolicyRequest.ProtoReflect.Descriptor instead. func (*UpdateActorEgressPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{74} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{79} } func (x *UpdateActorEgressPolicyRequest) GetActor() *ObjectRef { @@ -5786,7 +6049,7 @@ type DeleteActorEgressPolicyRequest struct { func (x *DeleteActorEgressPolicyRequest) Reset() { *x = DeleteActorEgressPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[75] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5798,7 +6061,7 @@ func (x *DeleteActorEgressPolicyRequest) String() string { func (*DeleteActorEgressPolicyRequest) ProtoMessage() {} func (x *DeleteActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[75] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[80] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5811,7 +6074,7 @@ func (x *DeleteActorEgressPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteActorEgressPolicyRequest.ProtoReflect.Descriptor instead. func (*DeleteActorEgressPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{75} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{80} } func (x *DeleteActorEgressPolicyRequest) GetActor() *ObjectRef { @@ -5846,7 +6109,7 @@ type GetTagRequest struct { func (x *GetTagRequest) Reset() { *x = GetTagRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[76] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5858,7 +6121,7 @@ func (x *GetTagRequest) String() string { func (*GetTagRequest) ProtoMessage() {} func (x *GetTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[76] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[81] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5871,7 +6134,7 @@ func (x *GetTagRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetTagRequest.ProtoReflect.Descriptor instead. func (*GetTagRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{76} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{81} } func (x *GetTagRequest) GetTag() *ObjectRef { @@ -5910,7 +6173,7 @@ type MintActorJwtRequest struct { func (x *MintActorJwtRequest) Reset() { *x = MintActorJwtRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[77] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5922,7 +6185,7 @@ func (x *MintActorJwtRequest) String() string { func (*MintActorJwtRequest) ProtoMessage() {} func (x *MintActorJwtRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[77] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[82] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5935,7 +6198,7 @@ func (x *MintActorJwtRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MintActorJwtRequest.ProtoReflect.Descriptor instead. func (*MintActorJwtRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{77} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{82} } func (x *MintActorJwtRequest) GetActor() *ObjectRef { @@ -5990,7 +6253,7 @@ type MintActorJwtResponse struct { func (x *MintActorJwtResponse) Reset() { *x = MintActorJwtResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[78] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6002,7 +6265,7 @@ func (x *MintActorJwtResponse) String() string { func (*MintActorJwtResponse) ProtoMessage() {} func (x *MintActorJwtResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[78] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[83] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6015,7 +6278,7 @@ func (x *MintActorJwtResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MintActorJwtResponse.ProtoReflect.Descriptor instead. func (*MintActorJwtResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{78} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{83} } func (x *MintActorJwtResponse) GetActorJwt() string { @@ -6049,7 +6312,7 @@ type ListTagsRequest struct { func (x *ListTagsRequest) Reset() { *x = ListTagsRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[79] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[84] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6061,7 +6324,7 @@ func (x *ListTagsRequest) String() string { func (*ListTagsRequest) ProtoMessage() {} func (x *ListTagsRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[79] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[84] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6074,7 +6337,7 @@ func (x *ListTagsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListTagsRequest.ProtoReflect.Descriptor instead. func (*ListTagsRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{79} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{84} } func (x *ListTagsRequest) GetAtespace() string { @@ -6101,7 +6364,7 @@ type ListTagsResponse struct { func (x *ListTagsResponse) Reset() { *x = ListTagsResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[80] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[85] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6113,7 +6376,7 @@ func (x *ListTagsResponse) String() string { func (*ListTagsResponse) ProtoMessage() {} func (x *ListTagsResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[80] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[85] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6126,7 +6389,7 @@ func (x *ListTagsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListTagsResponse.ProtoReflect.Descriptor instead. func (*ListTagsResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{80} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{85} } func (x *ListTagsResponse) GetTags() []*Tag { @@ -6171,7 +6434,7 @@ type CreateTagRequest struct { func (x *CreateTagRequest) Reset() { *x = CreateTagRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[81] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[86] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6183,7 +6446,7 @@ func (x *CreateTagRequest) String() string { func (*CreateTagRequest) ProtoMessage() {} func (x *CreateTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[81] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[86] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6196,7 +6459,7 @@ func (x *CreateTagRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateTagRequest.ProtoReflect.Descriptor instead. func (*CreateTagRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{81} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{86} } func (x *CreateTagRequest) GetTag() *Tag { @@ -6226,7 +6489,7 @@ type UpdateTagRequest struct { func (x *UpdateTagRequest) Reset() { *x = UpdateTagRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[82] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[87] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6238,7 +6501,7 @@ func (x *UpdateTagRequest) String() string { func (*UpdateTagRequest) ProtoMessage() {} func (x *UpdateTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[82] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[87] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6251,7 +6514,7 @@ func (x *UpdateTagRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateTagRequest.ProtoReflect.Descriptor instead. func (*UpdateTagRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{82} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{87} } func (x *UpdateTagRequest) GetTag() *Tag { @@ -6276,7 +6539,7 @@ type DeleteTagRequest struct { func (x *DeleteTagRequest) Reset() { *x = DeleteTagRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[83] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[88] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6288,7 +6551,7 @@ func (x *DeleteTagRequest) String() string { func (*DeleteTagRequest) ProtoMessage() {} func (x *DeleteTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[83] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[88] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6301,7 +6564,7 @@ func (x *DeleteTagRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteTagRequest.ProtoReflect.Descriptor instead. func (*DeleteTagRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{83} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{88} } func (x *DeleteTagRequest) GetTag() *ObjectRef { @@ -6340,7 +6603,7 @@ type DeleteOptions struct { func (x *DeleteOptions) Reset() { *x = DeleteOptions{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[84] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[89] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6352,7 +6615,7 @@ func (x *DeleteOptions) String() string { func (*DeleteOptions) ProtoMessage() {} func (x *DeleteOptions) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[84] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[89] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6365,7 +6628,7 @@ func (x *DeleteOptions) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteOptions.ProtoReflect.Descriptor instead. func (*DeleteOptions) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{84} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{89} } func (x *DeleteOptions) GetVersion() int64 { @@ -6404,7 +6667,7 @@ type ListOptions struct { func (x *ListOptions) Reset() { *x = ListOptions{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[85] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[90] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6416,7 +6679,7 @@ func (x *ListOptions) String() string { func (*ListOptions) ProtoMessage() {} func (x *ListOptions) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[85] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[90] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6429,7 +6692,7 @@ func (x *ListOptions) ProtoReflect() protoreflect.Message { // Deprecated: Use ListOptions.ProtoReflect.Descriptor instead. func (*ListOptions) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{85} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{90} } func (x *ListOptions) GetPageSize() int32 { @@ -6465,7 +6728,7 @@ type ListWorkerActorAssignmentsRequest struct { func (x *ListWorkerActorAssignmentsRequest) Reset() { *x = ListWorkerActorAssignmentsRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[86] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[91] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6477,7 +6740,7 @@ func (x *ListWorkerActorAssignmentsRequest) String() string { func (*ListWorkerActorAssignmentsRequest) ProtoMessage() {} func (x *ListWorkerActorAssignmentsRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[86] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[91] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6490,7 +6753,7 @@ func (x *ListWorkerActorAssignmentsRequest) ProtoReflect() protoreflect.Message // Deprecated: Use ListWorkerActorAssignmentsRequest.ProtoReflect.Descriptor instead. func (*ListWorkerActorAssignmentsRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{86} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{91} } func (x *ListWorkerActorAssignmentsRequest) GetWorker() *ObjectRef { @@ -6520,7 +6783,7 @@ type ListWorkerActorAssignmentsResponse struct { func (x *ListWorkerActorAssignmentsResponse) Reset() { *x = ListWorkerActorAssignmentsResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[87] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[92] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6532,7 +6795,7 @@ func (x *ListWorkerActorAssignmentsResponse) String() string { func (*ListWorkerActorAssignmentsResponse) ProtoMessage() {} func (x *ListWorkerActorAssignmentsResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[87] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[92] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6545,7 +6808,7 @@ func (x *ListWorkerActorAssignmentsResponse) ProtoReflect() protoreflect.Message // Deprecated: Use ListWorkerActorAssignmentsResponse.ProtoReflect.Descriptor instead. func (*ListWorkerActorAssignmentsResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{87} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{92} } func (x *ListWorkerActorAssignmentsResponse) GetActorAssignments() []*ActorAssignment { @@ -6574,7 +6837,7 @@ type ListWorkersRequest struct { func (x *ListWorkersRequest) Reset() { *x = ListWorkersRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[88] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[93] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6586,7 +6849,7 @@ func (x *ListWorkersRequest) String() string { func (*ListWorkersRequest) ProtoMessage() {} func (x *ListWorkersRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[88] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[93] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6599,7 +6862,7 @@ func (x *ListWorkersRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkersRequest.ProtoReflect.Descriptor instead. func (*ListWorkersRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{88} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{93} } func (x *ListWorkersRequest) GetOptions() *ListOptions { @@ -6621,7 +6884,7 @@ type ListWorkersResponse struct { func (x *ListWorkersResponse) Reset() { *x = ListWorkersResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[89] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[94] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6633,7 +6896,7 @@ func (x *ListWorkersResponse) String() string { func (*ListWorkersResponse) ProtoMessage() {} func (x *ListWorkersResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[89] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[94] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6646,7 +6909,7 @@ func (x *ListWorkersResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkersResponse.ProtoReflect.Descriptor instead. func (*ListWorkersResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{89} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{94} } func (x *ListWorkersResponse) GetWorkers() []*Worker { @@ -6676,7 +6939,7 @@ type GetWorkerRequest struct { func (x *GetWorkerRequest) Reset() { *x = GetWorkerRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[90] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[95] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6688,7 +6951,7 @@ func (x *GetWorkerRequest) String() string { func (*GetWorkerRequest) ProtoMessage() {} func (x *GetWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[90] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[95] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6701,7 +6964,7 @@ func (x *GetWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetWorkerRequest.ProtoReflect.Descriptor instead. func (*GetWorkerRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{90} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{95} } func (x *GetWorkerRequest) GetWorker() *ObjectRef { @@ -6723,7 +6986,7 @@ type CreateWorkerRequest struct { func (x *CreateWorkerRequest) Reset() { *x = CreateWorkerRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[91] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[96] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6735,7 +6998,7 @@ func (x *CreateWorkerRequest) String() string { func (*CreateWorkerRequest) ProtoMessage() {} func (x *CreateWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[91] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[96] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6748,7 +7011,7 @@ func (x *CreateWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateWorkerRequest.ProtoReflect.Descriptor instead. func (*CreateWorkerRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{91} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{96} } func (x *CreateWorkerRequest) GetWorker() *Worker { @@ -6783,7 +7046,7 @@ type UpdateWorkerRequest struct { func (x *UpdateWorkerRequest) Reset() { *x = UpdateWorkerRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[92] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[97] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6795,7 +7058,7 @@ func (x *UpdateWorkerRequest) String() string { func (*UpdateWorkerRequest) ProtoMessage() {} func (x *UpdateWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[92] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[97] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6808,7 +7071,7 @@ func (x *UpdateWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateWorkerRequest.ProtoReflect.Descriptor instead. func (*UpdateWorkerRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{92} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{97} } func (x *UpdateWorkerRequest) GetWorker() *Worker { @@ -6835,7 +7098,7 @@ type DeleteWorkerRequest struct { func (x *DeleteWorkerRequest) Reset() { *x = DeleteWorkerRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[93] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[98] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6847,7 +7110,7 @@ func (x *DeleteWorkerRequest) String() string { func (*DeleteWorkerRequest) ProtoMessage() {} func (x *DeleteWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[93] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[98] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6860,7 +7123,7 @@ func (x *DeleteWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteWorkerRequest.ProtoReflect.Descriptor instead. func (*DeleteWorkerRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{93} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{98} } func (x *DeleteWorkerRequest) GetWorker() *ObjectRef { @@ -6890,7 +7153,7 @@ type DrainWorkerRequest struct { func (x *DrainWorkerRequest) Reset() { *x = DrainWorkerRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[94] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[99] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6902,7 +7165,7 @@ func (x *DrainWorkerRequest) String() string { func (*DrainWorkerRequest) ProtoMessage() {} func (x *DrainWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[94] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[99] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6915,7 +7178,7 @@ func (x *DrainWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DrainWorkerRequest.ProtoReflect.Descriptor instead. func (*DrainWorkerRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{94} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{99} } func (x *DrainWorkerRequest) GetWorker() *ObjectRef { @@ -6936,7 +7199,7 @@ type DrainWorkerResponse struct { func (x *DrainWorkerResponse) Reset() { *x = DrainWorkerResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[95] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[100] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6948,7 +7211,7 @@ func (x *DrainWorkerResponse) String() string { func (*DrainWorkerResponse) ProtoMessage() {} func (x *DrainWorkerResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[95] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[100] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6961,7 +7224,7 @@ func (x *DrainWorkerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DrainWorkerResponse.ProtoReflect.Descriptor instead. func (*DrainWorkerResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{95} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{100} } func (x *DrainWorkerResponse) GetWorker() *Worker { @@ -6985,7 +7248,7 @@ type MarkWorkerAvailableRequest struct { func (x *MarkWorkerAvailableRequest) Reset() { *x = MarkWorkerAvailableRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[96] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[101] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6997,7 +7260,7 @@ func (x *MarkWorkerAvailableRequest) String() string { func (*MarkWorkerAvailableRequest) ProtoMessage() {} func (x *MarkWorkerAvailableRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[96] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[101] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7010,7 +7273,7 @@ func (x *MarkWorkerAvailableRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MarkWorkerAvailableRequest.ProtoReflect.Descriptor instead. func (*MarkWorkerAvailableRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{96} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{101} } func (x *MarkWorkerAvailableRequest) GetWorker() *ObjectRef { @@ -7031,7 +7294,7 @@ type MarkWorkerAvailableResponse struct { func (x *MarkWorkerAvailableResponse) Reset() { *x = MarkWorkerAvailableResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[97] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[102] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7043,7 +7306,7 @@ func (x *MarkWorkerAvailableResponse) String() string { func (*MarkWorkerAvailableResponse) ProtoMessage() {} func (x *MarkWorkerAvailableResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[97] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[102] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7056,7 +7319,7 @@ func (x *MarkWorkerAvailableResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MarkWorkerAvailableResponse.ProtoReflect.Descriptor instead. func (*MarkWorkerAvailableResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{97} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{102} } func (x *MarkWorkerAvailableResponse) GetWorker() *Worker { @@ -7080,7 +7343,7 @@ type MarkWorkerUnavailableRequest struct { func (x *MarkWorkerUnavailableRequest) Reset() { *x = MarkWorkerUnavailableRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[98] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[103] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7092,7 +7355,7 @@ func (x *MarkWorkerUnavailableRequest) String() string { func (*MarkWorkerUnavailableRequest) ProtoMessage() {} func (x *MarkWorkerUnavailableRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[98] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[103] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7105,7 +7368,7 @@ func (x *MarkWorkerUnavailableRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MarkWorkerUnavailableRequest.ProtoReflect.Descriptor instead. func (*MarkWorkerUnavailableRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{98} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{103} } func (x *MarkWorkerUnavailableRequest) GetWorker() *ObjectRef { @@ -7126,7 +7389,7 @@ type MarkWorkerUnavailableResponse struct { func (x *MarkWorkerUnavailableResponse) Reset() { *x = MarkWorkerUnavailableResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[99] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[104] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7138,7 +7401,7 @@ func (x *MarkWorkerUnavailableResponse) String() string { func (*MarkWorkerUnavailableResponse) ProtoMessage() {} func (x *MarkWorkerUnavailableResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[99] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[104] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7151,7 +7414,7 @@ func (x *MarkWorkerUnavailableResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MarkWorkerUnavailableResponse.ProtoReflect.Descriptor instead. func (*MarkWorkerUnavailableResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{99} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{104} } func (x *MarkWorkerUnavailableResponse) GetWorker() *Worker { @@ -7180,7 +7443,7 @@ type ListActorsRequest struct { func (x *ListActorsRequest) Reset() { *x = ListActorsRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[100] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[105] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7192,7 +7455,7 @@ func (x *ListActorsRequest) String() string { func (*ListActorsRequest) ProtoMessage() {} func (x *ListActorsRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[100] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[105] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7205,7 +7468,7 @@ func (x *ListActorsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListActorsRequest.ProtoReflect.Descriptor instead. func (*ListActorsRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{100} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{105} } func (x *ListActorsRequest) GetAtespace() string { @@ -7234,7 +7497,7 @@ type ListActorsResponse struct { func (x *ListActorsResponse) Reset() { *x = ListActorsResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[101] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[106] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7246,7 +7509,7 @@ func (x *ListActorsResponse) String() string { func (*ListActorsResponse) ProtoMessage() {} func (x *ListActorsResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[101] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[106] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7259,7 +7522,7 @@ func (x *ListActorsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListActorsResponse.ProtoReflect.Descriptor instead. func (*ListActorsResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{101} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{106} } func (x *ListActorsResponse) GetActors() []*Actor { @@ -7347,7 +7610,7 @@ type Worker struct { func (x *Worker) Reset() { *x = Worker{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[102] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[107] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7359,7 +7622,7 @@ func (x *Worker) String() string { func (*Worker) ProtoMessage() {} func (x *Worker) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[102] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[107] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7372,7 +7635,7 @@ func (x *Worker) ProtoReflect() protoreflect.Message { // Deprecated: Use Worker.ProtoReflect.Descriptor instead. func (*Worker) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{102} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{107} } func (x *Worker) GetMetadata() *ResourceMetadata { @@ -7514,7 +7777,7 @@ type WorkerStatus struct { func (x *WorkerStatus) Reset() { *x = WorkerStatus{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[103] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[108] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7526,7 +7789,7 @@ func (x *WorkerStatus) String() string { func (*WorkerStatus) ProtoMessage() {} func (x *WorkerStatus) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[103] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[108] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7539,7 +7802,7 @@ func (x *WorkerStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkerStatus.ProtoReflect.Descriptor instead. func (*WorkerStatus) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{103} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{108} } func (x *WorkerStatus) GetState() WorkerState { @@ -7627,7 +7890,7 @@ type WorkerSandboxClass struct { func (x *WorkerSandboxClass) Reset() { *x = WorkerSandboxClass{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[104] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[109] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7639,7 +7902,7 @@ func (x *WorkerSandboxClass) String() string { func (*WorkerSandboxClass) ProtoMessage() {} func (x *WorkerSandboxClass) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[104] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[109] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7652,7 +7915,7 @@ func (x *WorkerSandboxClass) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkerSandboxClass.ProtoReflect.Descriptor instead. func (*WorkerSandboxClass) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{104} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{109} } func (x *WorkerSandboxClass) GetSandboxClass() string { @@ -7704,7 +7967,7 @@ type WorkerSandboxRuntime struct { func (x *WorkerSandboxRuntime) Reset() { *x = WorkerSandboxRuntime{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[105] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[110] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7716,7 +7979,7 @@ func (x *WorkerSandboxRuntime) String() string { func (*WorkerSandboxRuntime) ProtoMessage() {} func (x *WorkerSandboxRuntime) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[105] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[110] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7729,7 +7992,7 @@ func (x *WorkerSandboxRuntime) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkerSandboxRuntime.ProtoReflect.Descriptor instead. func (*WorkerSandboxRuntime) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{105} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{110} } func (x *WorkerSandboxRuntime) GetVersion() *VersionedSandboxCompat { @@ -7770,7 +8033,7 @@ type RuntimeOverhead struct { func (x *RuntimeOverhead) Reset() { *x = RuntimeOverhead{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[106] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[111] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7782,7 +8045,7 @@ func (x *RuntimeOverhead) String() string { func (*RuntimeOverhead) ProtoMessage() {} func (x *RuntimeOverhead) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[106] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[111] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7795,7 +8058,7 @@ func (x *RuntimeOverhead) ProtoReflect() protoreflect.Message { // Deprecated: Use RuntimeOverhead.ProtoReflect.Descriptor instead. func (*RuntimeOverhead) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{106} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{111} } func (x *RuntimeOverhead) GetMemoryBytes() int64 { @@ -7834,7 +8097,7 @@ type ActorSandboxRuntime struct { func (x *ActorSandboxRuntime) Reset() { *x = ActorSandboxRuntime{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[107] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[112] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7846,7 +8109,7 @@ func (x *ActorSandboxRuntime) String() string { func (*ActorSandboxRuntime) ProtoMessage() {} func (x *ActorSandboxRuntime) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[107] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[112] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7859,7 +8122,7 @@ func (x *ActorSandboxRuntime) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorSandboxRuntime.ProtoReflect.Descriptor instead. func (*ActorSandboxRuntime) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{107} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{112} } func (x *ActorSandboxRuntime) GetSandboxClass() string { @@ -7910,7 +8173,7 @@ type VersionedSandboxCompat struct { func (x *VersionedSandboxCompat) Reset() { *x = VersionedSandboxCompat{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[108] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[113] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7922,7 +8185,7 @@ func (x *VersionedSandboxCompat) String() string { func (*VersionedSandboxCompat) ProtoMessage() {} func (x *VersionedSandboxCompat) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[108] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[113] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7935,7 +8198,7 @@ func (x *VersionedSandboxCompat) ProtoReflect() protoreflect.Message { // Deprecated: Use VersionedSandboxCompat.ProtoReflect.Descriptor instead. func (*VersionedSandboxCompat) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{108} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{113} } func (x *VersionedSandboxCompat) GetSchemaVersion() string { @@ -7971,7 +8234,7 @@ type AttributeEntry struct { func (x *AttributeEntry) Reset() { *x = AttributeEntry{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[109] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[114] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7983,7 +8246,7 @@ func (x *AttributeEntry) String() string { func (*AttributeEntry) ProtoMessage() {} func (x *AttributeEntry) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[109] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[114] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7996,7 +8259,7 @@ func (x *AttributeEntry) ProtoReflect() protoreflect.Message { // Deprecated: Use AttributeEntry.ProtoReflect.Descriptor instead. func (*AttributeEntry) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{109} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{114} } func (x *AttributeEntry) GetKey() string { @@ -8043,7 +8306,7 @@ type WorkerResources struct { func (x *WorkerResources) Reset() { *x = WorkerResources{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[110] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[115] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8055,7 +8318,7 @@ func (x *WorkerResources) String() string { func (*WorkerResources) ProtoMessage() {} func (x *WorkerResources) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[110] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[115] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8068,7 +8331,7 @@ func (x *WorkerResources) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkerResources.ProtoReflect.Descriptor instead. func (*WorkerResources) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{110} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{115} } func (x *WorkerResources) GetCpuMillicores() int64 { @@ -8124,7 +8387,7 @@ type ActorAssignment struct { func (x *ActorAssignment) Reset() { *x = ActorAssignment{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[111] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[116] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8136,7 +8399,7 @@ func (x *ActorAssignment) String() string { func (*ActorAssignment) ProtoMessage() {} func (x *ActorAssignment) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[111] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[116] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8149,7 +8412,7 @@ func (x *ActorAssignment) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorAssignment.ProtoReflect.Descriptor instead. func (*ActorAssignment) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{111} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{116} } func (x *ActorAssignment) GetMetadata() *ResourceMetadata { @@ -8194,7 +8457,7 @@ type AcquireWorkerEpochRequest struct { func (x *AcquireWorkerEpochRequest) Reset() { *x = AcquireWorkerEpochRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[112] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[117] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8206,7 +8469,7 @@ func (x *AcquireWorkerEpochRequest) String() string { func (*AcquireWorkerEpochRequest) ProtoMessage() {} func (x *AcquireWorkerEpochRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[112] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[117] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8219,7 +8482,7 @@ func (x *AcquireWorkerEpochRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AcquireWorkerEpochRequest.ProtoReflect.Descriptor instead. func (*AcquireWorkerEpochRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{112} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{117} } func (x *AcquireWorkerEpochRequest) GetWorker() *ObjectRef { @@ -8239,7 +8502,7 @@ type AcquireWorkerEpochResponse struct { func (x *AcquireWorkerEpochResponse) Reset() { *x = AcquireWorkerEpochResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[113] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[118] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8251,7 +8514,7 @@ func (x *AcquireWorkerEpochResponse) String() string { func (*AcquireWorkerEpochResponse) ProtoMessage() {} func (x *AcquireWorkerEpochResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[113] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[118] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8264,7 +8527,7 @@ func (x *AcquireWorkerEpochResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AcquireWorkerEpochResponse.ProtoReflect.Descriptor instead. func (*AcquireWorkerEpochResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{113} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{118} } func (x *AcquireWorkerEpochResponse) GetEpoch() int64 { @@ -8307,7 +8570,7 @@ type RegisterWorkerRequest struct { func (x *RegisterWorkerRequest) Reset() { *x = RegisterWorkerRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[114] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[119] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8319,7 +8582,7 @@ func (x *RegisterWorkerRequest) String() string { func (*RegisterWorkerRequest) ProtoMessage() {} func (x *RegisterWorkerRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[114] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[119] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8332,7 +8595,7 @@ func (x *RegisterWorkerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RegisterWorkerRequest.ProtoReflect.Descriptor instead. func (*RegisterWorkerRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{114} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{119} } func (x *RegisterWorkerRequest) GetWorker() *ObjectRef { @@ -8373,7 +8636,7 @@ type RegisterWorkerResponse struct { func (x *RegisterWorkerResponse) Reset() { *x = RegisterWorkerResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[115] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[120] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8385,7 +8648,7 @@ func (x *RegisterWorkerResponse) String() string { func (*RegisterWorkerResponse) ProtoMessage() {} func (x *RegisterWorkerResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[115] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[120] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8398,7 +8661,7 @@ func (x *RegisterWorkerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RegisterWorkerResponse.ProtoReflect.Descriptor instead. func (*RegisterWorkerResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{115} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{120} } func (x *RegisterWorkerResponse) GetWorker() *Worker { @@ -8438,7 +8701,7 @@ type SetWorkerSandboxRuntimesRequest struct { func (x *SetWorkerSandboxRuntimesRequest) Reset() { *x = SetWorkerSandboxRuntimesRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[116] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[121] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8450,7 +8713,7 @@ func (x *SetWorkerSandboxRuntimesRequest) String() string { func (*SetWorkerSandboxRuntimesRequest) ProtoMessage() {} func (x *SetWorkerSandboxRuntimesRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[116] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[121] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8463,7 +8726,7 @@ func (x *SetWorkerSandboxRuntimesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SetWorkerSandboxRuntimesRequest.ProtoReflect.Descriptor instead. func (*SetWorkerSandboxRuntimesRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{116} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{121} } func (x *SetWorkerSandboxRuntimesRequest) GetWorker() *ObjectRef { @@ -8497,7 +8760,7 @@ type SetWorkerSandboxRuntimesResponse struct { func (x *SetWorkerSandboxRuntimesResponse) Reset() { *x = SetWorkerSandboxRuntimesResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[117] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[122] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8509,7 +8772,7 @@ func (x *SetWorkerSandboxRuntimesResponse) String() string { func (*SetWorkerSandboxRuntimesResponse) ProtoMessage() {} func (x *SetWorkerSandboxRuntimesResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[117] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[122] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8522,7 +8785,7 @@ func (x *SetWorkerSandboxRuntimesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SetWorkerSandboxRuntimesResponse.ProtoReflect.Descriptor instead. func (*SetWorkerSandboxRuntimesResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{117} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{122} } func (x *SetWorkerSandboxRuntimesResponse) GetWorker() *Worker { @@ -8569,7 +8832,7 @@ type MintWorkerActorCertificateRequest struct { func (x *MintWorkerActorCertificateRequest) Reset() { *x = MintWorkerActorCertificateRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[118] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[123] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8581,7 +8844,7 @@ func (x *MintWorkerActorCertificateRequest) String() string { func (*MintWorkerActorCertificateRequest) ProtoMessage() {} func (x *MintWorkerActorCertificateRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[118] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[123] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8594,7 +8857,7 @@ func (x *MintWorkerActorCertificateRequest) ProtoReflect() protoreflect.Message // Deprecated: Use MintWorkerActorCertificateRequest.ProtoReflect.Descriptor instead. func (*MintWorkerActorCertificateRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{118} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{123} } func (x *MintWorkerActorCertificateRequest) GetActor() *ObjectRef { @@ -8638,7 +8901,7 @@ type MintWorkerActorCertificateResponse struct { func (x *MintWorkerActorCertificateResponse) Reset() { *x = MintWorkerActorCertificateResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[119] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[124] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8650,7 +8913,7 @@ func (x *MintWorkerActorCertificateResponse) String() string { func (*MintWorkerActorCertificateResponse) ProtoMessage() {} func (x *MintWorkerActorCertificateResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[119] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[124] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8663,7 +8926,7 @@ func (x *MintWorkerActorCertificateResponse) ProtoReflect() protoreflect.Message // Deprecated: Use MintWorkerActorCertificateResponse.ProtoReflect.Descriptor instead. func (*MintWorkerActorCertificateResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{119} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{124} } func (x *MintWorkerActorCertificateResponse) GetActorCertificates() [][]byte { @@ -8704,7 +8967,7 @@ type MintWorkerActorJwtRequest struct { func (x *MintWorkerActorJwtRequest) Reset() { *x = MintWorkerActorJwtRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[120] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[125] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8716,7 +8979,7 @@ func (x *MintWorkerActorJwtRequest) String() string { func (*MintWorkerActorJwtRequest) ProtoMessage() {} func (x *MintWorkerActorJwtRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[120] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[125] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8729,7 +8992,7 @@ func (x *MintWorkerActorJwtRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MintWorkerActorJwtRequest.ProtoReflect.Descriptor instead. func (*MintWorkerActorJwtRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{120} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{125} } func (x *MintWorkerActorJwtRequest) GetActor() *ObjectRef { @@ -8777,7 +9040,7 @@ type MintWorkerActorJwtResponse struct { func (x *MintWorkerActorJwtResponse) Reset() { *x = MintWorkerActorJwtResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[121] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[126] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8789,7 +9052,7 @@ func (x *MintWorkerActorJwtResponse) String() string { func (*MintWorkerActorJwtResponse) ProtoMessage() {} func (x *MintWorkerActorJwtResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[121] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[126] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8802,7 +9065,7 @@ func (x *MintWorkerActorJwtResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MintWorkerActorJwtResponse.ProtoReflect.Descriptor instead. func (*MintWorkerActorJwtResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{121} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{126} } func (x *MintWorkerActorJwtResponse) GetActorJwt() string { @@ -8853,7 +9116,7 @@ type RequestActorSuspendRequest struct { func (x *RequestActorSuspendRequest) Reset() { *x = RequestActorSuspendRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[122] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[127] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8865,7 +9128,7 @@ func (x *RequestActorSuspendRequest) String() string { func (*RequestActorSuspendRequest) ProtoMessage() {} func (x *RequestActorSuspendRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[122] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[127] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8878,7 +9141,7 @@ func (x *RequestActorSuspendRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RequestActorSuspendRequest.ProtoReflect.Descriptor instead. func (*RequestActorSuspendRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{122} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{127} } func (x *RequestActorSuspendRequest) GetWorker() *ObjectRef { @@ -8912,7 +9175,7 @@ type RequestActorSuspendResponse struct { func (x *RequestActorSuspendResponse) Reset() { *x = RequestActorSuspendResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[123] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[128] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8924,7 +9187,7 @@ func (x *RequestActorSuspendResponse) String() string { func (*RequestActorSuspendResponse) ProtoMessage() {} func (x *RequestActorSuspendResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[123] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[128] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8937,7 +9200,7 @@ func (x *RequestActorSuspendResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RequestActorSuspendResponse.ProtoReflect.Descriptor instead. func (*RequestActorSuspendResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{123} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{128} } func (x *RequestActorSuspendResponse) GetActor() *Actor { @@ -8977,7 +9240,7 @@ type ReportActorCrashedRequest struct { func (x *ReportActorCrashedRequest) Reset() { *x = ReportActorCrashedRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[124] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[129] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8989,7 +9252,7 @@ func (x *ReportActorCrashedRequest) String() string { func (*ReportActorCrashedRequest) ProtoMessage() {} func (x *ReportActorCrashedRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[124] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[129] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9002,7 +9265,7 @@ func (x *ReportActorCrashedRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportActorCrashedRequest.ProtoReflect.Descriptor instead. func (*ReportActorCrashedRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{124} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{129} } func (x *ReportActorCrashedRequest) GetWorker() *ObjectRef { @@ -9043,7 +9306,7 @@ type ReportActorCrashedResponse struct { func (x *ReportActorCrashedResponse) Reset() { *x = ReportActorCrashedResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[125] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[130] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9055,7 +9318,7 @@ func (x *ReportActorCrashedResponse) String() string { func (*ReportActorCrashedResponse) ProtoMessage() {} func (x *ReportActorCrashedResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[125] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[130] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9068,7 +9331,7 @@ func (x *ReportActorCrashedResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportActorCrashedResponse.ProtoReflect.Descriptor instead. func (*ReportActorCrashedResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{125} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{130} } func (x *ReportActorCrashedResponse) GetActor() *Actor { @@ -9099,7 +9362,7 @@ type ReportActorSnapshotStateRequest struct { func (x *ReportActorSnapshotStateRequest) Reset() { *x = ReportActorSnapshotStateRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[126] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[131] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9111,7 +9374,7 @@ func (x *ReportActorSnapshotStateRequest) String() string { func (*ReportActorSnapshotStateRequest) ProtoMessage() {} func (x *ReportActorSnapshotStateRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[126] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[131] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9124,7 +9387,7 @@ func (x *ReportActorSnapshotStateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportActorSnapshotStateRequest.ProtoReflect.Descriptor instead. func (*ReportActorSnapshotStateRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{126} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{131} } func (x *ReportActorSnapshotStateRequest) GetActor() *ObjectRef { @@ -9156,7 +9419,7 @@ type ReportActorSnapshotStateResponse struct { func (x *ReportActorSnapshotStateResponse) Reset() { *x = ReportActorSnapshotStateResponse{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[127] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[132] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9168,7 +9431,7 @@ func (x *ReportActorSnapshotStateResponse) String() string { func (*ReportActorSnapshotStateResponse) ProtoMessage() {} func (x *ReportActorSnapshotStateResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[127] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[132] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9181,7 +9444,7 @@ func (x *ReportActorSnapshotStateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportActorSnapshotStateResponse.ProtoReflect.Descriptor instead. func (*ReportActorSnapshotStateResponse) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{127} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{132} } // ActorSnapshotState is what atelet holds for one Actor on its node. It @@ -9215,7 +9478,7 @@ type ActorSnapshotState struct { func (x *ActorSnapshotState) Reset() { *x = ActorSnapshotState{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[128] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[133] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9227,7 +9490,7 @@ func (x *ActorSnapshotState) String() string { func (*ActorSnapshotState) ProtoMessage() {} func (x *ActorSnapshotState) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[128] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[133] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9240,7 +9503,7 @@ func (x *ActorSnapshotState) ProtoReflect() protoreflect.Message { // Deprecated: Use ActorSnapshotState.ProtoReflect.Descriptor instead. func (*ActorSnapshotState) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{128} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{133} } func (x *ActorSnapshotState) GetLatestLocal() *SnapshotReport { @@ -9312,7 +9575,7 @@ type SnapshotReport struct { func (x *SnapshotReport) Reset() { *x = SnapshotReport{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[129] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[134] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9324,7 +9587,7 @@ func (x *SnapshotReport) String() string { func (*SnapshotReport) ProtoMessage() {} func (x *SnapshotReport) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[129] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[134] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9337,7 +9600,7 @@ func (x *SnapshotReport) ProtoReflect() protoreflect.Message { // Deprecated: Use SnapshotReport.ProtoReflect.Descriptor instead. func (*SnapshotReport) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{129} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{134} } func (x *SnapshotReport) GetUuid() string { @@ -9407,7 +9670,7 @@ type AccessPolicy struct { func (x *AccessPolicy) Reset() { *x = AccessPolicy{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[130] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[135] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9419,7 +9682,7 @@ func (x *AccessPolicy) String() string { func (*AccessPolicy) ProtoMessage() {} func (x *AccessPolicy) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[130] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[135] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9432,7 +9695,7 @@ func (x *AccessPolicy) ProtoReflect() protoreflect.Message { // Deprecated: Use AccessPolicy.ProtoReflect.Descriptor instead. func (*AccessPolicy) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{130} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{135} } func (x *AccessPolicy) GetMetadata() *ResourceMetadata { @@ -9474,7 +9737,7 @@ type Binding struct { func (x *Binding) Reset() { *x = Binding{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[131] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[136] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9486,7 +9749,7 @@ func (x *Binding) String() string { func (*Binding) ProtoMessage() {} func (x *Binding) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[131] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[136] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9499,7 +9762,7 @@ func (x *Binding) ProtoReflect() protoreflect.Message { // Deprecated: Use Binding.ProtoReflect.Descriptor instead. func (*Binding) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{131} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{136} } func (x *Binding) GetRole() string { @@ -9531,7 +9794,7 @@ type GetGlobalAccessPolicyRequest struct { func (x *GetGlobalAccessPolicyRequest) Reset() { *x = GetGlobalAccessPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[132] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[137] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9543,7 +9806,7 @@ func (x *GetGlobalAccessPolicyRequest) String() string { func (*GetGlobalAccessPolicyRequest) ProtoMessage() {} func (x *GetGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[132] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[137] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9556,7 +9819,7 @@ func (x *GetGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetGlobalAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*GetGlobalAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{132} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{137} } func (x *GetGlobalAccessPolicyRequest) GetName() string { @@ -9580,7 +9843,7 @@ type CreateGlobalAccessPolicyRequest struct { func (x *CreateGlobalAccessPolicyRequest) Reset() { *x = CreateGlobalAccessPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[133] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[138] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9592,7 +9855,7 @@ func (x *CreateGlobalAccessPolicyRequest) String() string { func (*CreateGlobalAccessPolicyRequest) ProtoMessage() {} func (x *CreateGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[133] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[138] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9605,7 +9868,7 @@ func (x *CreateGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateGlobalAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*CreateGlobalAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{133} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{138} } func (x *CreateGlobalAccessPolicyRequest) GetAccessPolicy() *AccessPolicy { @@ -9629,7 +9892,7 @@ type UpdateGlobalAccessPolicyRequest struct { func (x *UpdateGlobalAccessPolicyRequest) Reset() { *x = UpdateGlobalAccessPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[134] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[139] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9641,7 +9904,7 @@ func (x *UpdateGlobalAccessPolicyRequest) String() string { func (*UpdateGlobalAccessPolicyRequest) ProtoMessage() {} func (x *UpdateGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[134] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[139] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9654,7 +9917,7 @@ func (x *UpdateGlobalAccessPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateGlobalAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*UpdateGlobalAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{134} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{139} } func (x *UpdateGlobalAccessPolicyRequest) GetAccessPolicy() *AccessPolicy { @@ -9684,7 +9947,7 @@ type GetAtespaceAccessPolicyRequest struct { func (x *GetAtespaceAccessPolicyRequest) Reset() { *x = GetAtespaceAccessPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[135] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[140] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9696,7 +9959,7 @@ func (x *GetAtespaceAccessPolicyRequest) String() string { func (*GetAtespaceAccessPolicyRequest) ProtoMessage() {} func (x *GetAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[135] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[140] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9709,7 +9972,7 @@ func (x *GetAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAtespaceAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*GetAtespaceAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{135} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{140} } func (x *GetAtespaceAccessPolicyRequest) GetAtespace() *ObjectRef { @@ -9745,7 +10008,7 @@ type CreateAtespaceAccessPolicyRequest struct { func (x *CreateAtespaceAccessPolicyRequest) Reset() { *x = CreateAtespaceAccessPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[136] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[141] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9757,7 +10020,7 @@ func (x *CreateAtespaceAccessPolicyRequest) String() string { func (*CreateAtespaceAccessPolicyRequest) ProtoMessage() {} func (x *CreateAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[136] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[141] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9770,7 +10033,7 @@ func (x *CreateAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message // Deprecated: Use CreateAtespaceAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*CreateAtespaceAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{136} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{141} } func (x *CreateAtespaceAccessPolicyRequest) GetAtespace() *ObjectRef { @@ -9806,7 +10069,7 @@ type UpdateAtespaceAccessPolicyRequest struct { func (x *UpdateAtespaceAccessPolicyRequest) Reset() { *x = UpdateAtespaceAccessPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[137] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[142] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9818,7 +10081,7 @@ func (x *UpdateAtespaceAccessPolicyRequest) String() string { func (*UpdateAtespaceAccessPolicyRequest) ProtoMessage() {} func (x *UpdateAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[137] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[142] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9831,7 +10094,7 @@ func (x *UpdateAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message // Deprecated: Use UpdateAtespaceAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*UpdateAtespaceAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{137} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{142} } func (x *UpdateAtespaceAccessPolicyRequest) GetAtespace() *ObjectRef { @@ -9872,7 +10135,7 @@ type DeleteAtespaceAccessPolicyRequest struct { func (x *DeleteAtespaceAccessPolicyRequest) Reset() { *x = DeleteAtespaceAccessPolicyRequest{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[138] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[143] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9884,7 +10147,7 @@ func (x *DeleteAtespaceAccessPolicyRequest) String() string { func (*DeleteAtespaceAccessPolicyRequest) ProtoMessage() {} func (x *DeleteAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[138] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[143] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9897,7 +10160,7 @@ func (x *DeleteAtespaceAccessPolicyRequest) ProtoReflect() protoreflect.Message // Deprecated: Use DeleteAtespaceAccessPolicyRequest.ProtoReflect.Descriptor instead. func (*DeleteAtespaceAccessPolicyRequest) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{138} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{143} } func (x *DeleteAtespaceAccessPolicyRequest) GetAtespace() *ObjectRef { @@ -9943,7 +10206,7 @@ type ResourceAnnotation struct { func (x *ResourceAnnotation) Reset() { *x = ResourceAnnotation{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[139] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[144] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9955,7 +10218,7 @@ func (x *ResourceAnnotation) String() string { func (*ResourceAnnotation) ProtoMessage() {} func (x *ResourceAnnotation) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[139] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[144] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9968,7 +10231,7 @@ func (x *ResourceAnnotation) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceAnnotation.ProtoReflect.Descriptor instead. func (*ResourceAnnotation) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{139} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{144} } func (x *ResourceAnnotation) GetParents() []string { @@ -10011,7 +10274,7 @@ type MethodAnnotation struct { func (x *MethodAnnotation) Reset() { *x = MethodAnnotation{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[140] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[145] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10023,7 +10286,7 @@ func (x *MethodAnnotation) String() string { func (*MethodAnnotation) ProtoMessage() {} func (x *MethodAnnotation) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[140] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[145] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10036,7 +10299,7 @@ func (x *MethodAnnotation) ProtoReflect() protoreflect.Message { // Deprecated: Use MethodAnnotation.ProtoReflect.Descriptor instead. func (*MethodAnnotation) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{140} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{145} } func (x *MethodAnnotation) GetResource() string { @@ -10317,6 +10580,18 @@ const file_api_ateapi_v1_ateapi_proto_rawDesc = "" + "\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\"\x91\x01\n" + "\x15DeleteAtespaceRequest\x12:\n" + "\batespace\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\batespace\x12<\n" + + "\aoptions\x18\x02 \x01(\v2\".substrate.ateapi.v1.DeleteOptionsR\aoptions\"\x80\x01\n" + + " CreateExternalVolumeClassRequest\x12\\\n" + + "\x15external_volume_class\x18\x01 \x01(\v2(.substrate.ateapi.v1.ExternalVolumeClassR\x13externalVolumeClass\"s\n" + + "\x1dGetExternalVolumeClassRequest\x12R\n" + + "\x15external_volume_class\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x13externalVolumeClass\"^\n" + + " ListExternalVolumeClassesRequest\x12:\n" + + "\aoptions\x18\x01 \x01(\v2 .substrate.ateapi.v1.ListOptionsR\aoptions\"\xad\x01\n" + + "!ListExternalVolumeClassesResponse\x12`\n" + + "\x17external_volume_classes\x18\x01 \x03(\v2(.substrate.ateapi.v1.ExternalVolumeClassR\x15externalVolumeClasses\x12&\n" + + "\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\"\xb4\x01\n" + + " DeleteExternalVolumeClassRequest\x12R\n" + + "\x15external_volume_class\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x13externalVolumeClass\x12<\n" + "\aoptions\x18\x02 \x01(\v2\".substrate.ateapi.v1.DeleteOptionsR\aoptions\"g\n" + "\x1aCreateActorTemplateRequest\x12I\n" + "\x0eactor_template\x18\x01 \x01(\v2\".substrate.ateapi.v1.ActorTemplateR\ractorTemplate\"`\n" + @@ -10638,7 +10913,7 @@ const file_api_ateapi_v1_ateapi_proto_rawDesc = "" + "\x05Scope\x12\x15\n" + "\x11SCOPE_UNSPECIFIED\x10\x00\x12\x12\n" + "\x0eSCOPE_ATESPACE\x10\x01\x12\x10\n" + - "\fSCOPE_GLOBAL\x10\x022\xca&\n" + + "\fSCOPE_GLOBAL\x10\x022\xba+\n" + "\aControl\x12Y\n" + "\bGetActor\x12$.substrate.ateapi.v1.GetActorRequest\x1a\x1a.substrate.ateapi.v1.Actor\"\v\x82\xb5\x18\a\n" + "\x05Actor\x12_\n" + @@ -10706,7 +10981,15 @@ const file_api_ateapi_v1_ateapi_proto_rawDesc = "" + "\bAtespace\x12k\n" + "\x0eDeleteAtespace\x12*.substrate.ateapi.v1.DeleteAtespaceRequest\x1a\x1d.substrate.ateapi.v1.Atespace\"\x0e\x82\xb5\x18\n" + "\n" + - "\bAtespace\x12\x7f\n" + + "\bAtespace\x12\x97\x01\n" + + "\x19CreateExternalVolumeClass\x125.substrate.ateapi.v1.CreateExternalVolumeClassRequest\x1a(.substrate.ateapi.v1.ExternalVolumeClass\"\x19\x82\xb5\x18\x15\n" + + "\x13ExternalVolumeClass\x12\x91\x01\n" + + "\x16GetExternalVolumeClass\x122.substrate.ateapi.v1.GetExternalVolumeClassRequest\x1a(.substrate.ateapi.v1.ExternalVolumeClass\"\x19\x82\xb5\x18\x15\n" + + "\x13ExternalVolumeClass\x12\xa5\x01\n" + + "\x19ListExternalVolumeClasses\x125.substrate.ateapi.v1.ListExternalVolumeClassesRequest\x1a6.substrate.ateapi.v1.ListExternalVolumeClassesResponse\"\x19\x82\xb5\x18\x15\n" + + "\x13ExternalVolumeClass\x12\x97\x01\n" + + "\x19DeleteExternalVolumeClass\x125.substrate.ateapi.v1.DeleteExternalVolumeClassRequest\x1a(.substrate.ateapi.v1.ExternalVolumeClass\"\x19\x82\xb5\x18\x15\n" + + "\x13ExternalVolumeClass\x12\x7f\n" + "\x13CreateActorTemplate\x12/.substrate.ateapi.v1.CreateActorTemplateRequest\x1a\".substrate.ateapi.v1.ActorTemplate\"\x13\x82\xb5\x18\x0f\n" + "\rActorTemplate\x12y\n" + "\x10GetActorTemplate\x12,.substrate.ateapi.v1.GetActorTemplateRequest\x1a\".substrate.ateapi.v1.ActorTemplate\"\x13\x82\xb5\x18\x0f\n" + @@ -10754,7 +11037,7 @@ func file_api_ateapi_v1_ateapi_proto_rawDescGZIP() []byte { } var file_api_ateapi_v1_ateapi_proto_enumTypes = make([]protoimpl.EnumInfo, 10) -var file_api_ateapi_v1_ateapi_proto_msgTypes = make([]protoimpl.MessageInfo, 145) +var file_api_ateapi_v1_ateapi_proto_msgTypes = make([]protoimpl.MessageInfo, 150) var file_api_ateapi_v1_ateapi_proto_goTypes = []any{ (SnapshotOwner)(0), // 0: substrate.ateapi.v1.SnapshotOwner (SnapshotStorageState)(0), // 1: substrate.ateapi.v1.SnapshotStorageState @@ -10822,98 +11105,103 @@ var file_api_ateapi_v1_ateapi_proto_goTypes = []any{ (*ListAtespacesRequest)(nil), // 63: substrate.ateapi.v1.ListAtespacesRequest (*ListAtespacesResponse)(nil), // 64: substrate.ateapi.v1.ListAtespacesResponse (*DeleteAtespaceRequest)(nil), // 65: substrate.ateapi.v1.DeleteAtespaceRequest - (*CreateActorTemplateRequest)(nil), // 66: substrate.ateapi.v1.CreateActorTemplateRequest - (*GetActorTemplateRequest)(nil), // 67: substrate.ateapi.v1.GetActorTemplateRequest - (*ListActorTemplatesRequest)(nil), // 68: substrate.ateapi.v1.ListActorTemplatesRequest - (*ListActorTemplatesResponse)(nil), // 69: substrate.ateapi.v1.ListActorTemplatesResponse - (*DeleteActorTemplateRequest)(nil), // 70: substrate.ateapi.v1.DeleteActorTemplateRequest - (*GetActorRequest)(nil), // 71: substrate.ateapi.v1.GetActorRequest - (*CreateActorRequest)(nil), // 72: substrate.ateapi.v1.CreateActorRequest - (*UpdateActorRequest)(nil), // 73: substrate.ateapi.v1.UpdateActorRequest - (*SuspendActorRequest)(nil), // 74: substrate.ateapi.v1.SuspendActorRequest - (*SuspendActorResponse)(nil), // 75: substrate.ateapi.v1.SuspendActorResponse - (*SuspendOptions)(nil), // 76: substrate.ateapi.v1.SuspendOptions - (*ResumeActorRequest)(nil), // 77: substrate.ateapi.v1.ResumeActorRequest - (*ResumeActorResponse)(nil), // 78: substrate.ateapi.v1.ResumeActorResponse - (*RevertActorRequest)(nil), // 79: substrate.ateapi.v1.RevertActorRequest - (*RevertActorResponse)(nil), // 80: substrate.ateapi.v1.RevertActorResponse - (*DeleteActorRequest)(nil), // 81: substrate.ateapi.v1.DeleteActorRequest - (*GetActorEgressPolicyRequest)(nil), // 82: substrate.ateapi.v1.GetActorEgressPolicyRequest - (*CreateActorEgressPolicyRequest)(nil), // 83: substrate.ateapi.v1.CreateActorEgressPolicyRequest - (*UpdateActorEgressPolicyRequest)(nil), // 84: substrate.ateapi.v1.UpdateActorEgressPolicyRequest - (*DeleteActorEgressPolicyRequest)(nil), // 85: substrate.ateapi.v1.DeleteActorEgressPolicyRequest - (*GetTagRequest)(nil), // 86: substrate.ateapi.v1.GetTagRequest - (*MintActorJwtRequest)(nil), // 87: substrate.ateapi.v1.MintActorJwtRequest - (*MintActorJwtResponse)(nil), // 88: substrate.ateapi.v1.MintActorJwtResponse - (*ListTagsRequest)(nil), // 89: substrate.ateapi.v1.ListTagsRequest - (*ListTagsResponse)(nil), // 90: substrate.ateapi.v1.ListTagsResponse - (*CreateTagRequest)(nil), // 91: substrate.ateapi.v1.CreateTagRequest - (*UpdateTagRequest)(nil), // 92: substrate.ateapi.v1.UpdateTagRequest - (*DeleteTagRequest)(nil), // 93: substrate.ateapi.v1.DeleteTagRequest - (*DeleteOptions)(nil), // 94: substrate.ateapi.v1.DeleteOptions - (*ListOptions)(nil), // 95: substrate.ateapi.v1.ListOptions - (*ListWorkerActorAssignmentsRequest)(nil), // 96: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest - (*ListWorkerActorAssignmentsResponse)(nil), // 97: substrate.ateapi.v1.ListWorkerActorAssignmentsResponse - (*ListWorkersRequest)(nil), // 98: substrate.ateapi.v1.ListWorkersRequest - (*ListWorkersResponse)(nil), // 99: substrate.ateapi.v1.ListWorkersResponse - (*GetWorkerRequest)(nil), // 100: substrate.ateapi.v1.GetWorkerRequest - (*CreateWorkerRequest)(nil), // 101: substrate.ateapi.v1.CreateWorkerRequest - (*UpdateWorkerRequest)(nil), // 102: substrate.ateapi.v1.UpdateWorkerRequest - (*DeleteWorkerRequest)(nil), // 103: substrate.ateapi.v1.DeleteWorkerRequest - (*DrainWorkerRequest)(nil), // 104: substrate.ateapi.v1.DrainWorkerRequest - (*DrainWorkerResponse)(nil), // 105: substrate.ateapi.v1.DrainWorkerResponse - (*MarkWorkerAvailableRequest)(nil), // 106: substrate.ateapi.v1.MarkWorkerAvailableRequest - (*MarkWorkerAvailableResponse)(nil), // 107: substrate.ateapi.v1.MarkWorkerAvailableResponse - (*MarkWorkerUnavailableRequest)(nil), // 108: substrate.ateapi.v1.MarkWorkerUnavailableRequest - (*MarkWorkerUnavailableResponse)(nil), // 109: substrate.ateapi.v1.MarkWorkerUnavailableResponse - (*ListActorsRequest)(nil), // 110: substrate.ateapi.v1.ListActorsRequest - (*ListActorsResponse)(nil), // 111: substrate.ateapi.v1.ListActorsResponse - (*Worker)(nil), // 112: substrate.ateapi.v1.Worker - (*WorkerStatus)(nil), // 113: substrate.ateapi.v1.WorkerStatus - (*WorkerSandboxClass)(nil), // 114: substrate.ateapi.v1.WorkerSandboxClass - (*WorkerSandboxRuntime)(nil), // 115: substrate.ateapi.v1.WorkerSandboxRuntime - (*RuntimeOverhead)(nil), // 116: substrate.ateapi.v1.RuntimeOverhead - (*ActorSandboxRuntime)(nil), // 117: substrate.ateapi.v1.ActorSandboxRuntime - (*VersionedSandboxCompat)(nil), // 118: substrate.ateapi.v1.VersionedSandboxCompat - (*AttributeEntry)(nil), // 119: substrate.ateapi.v1.AttributeEntry - (*WorkerResources)(nil), // 120: substrate.ateapi.v1.WorkerResources - (*ActorAssignment)(nil), // 121: substrate.ateapi.v1.ActorAssignment - (*AcquireWorkerEpochRequest)(nil), // 122: substrate.ateapi.v1.AcquireWorkerEpochRequest - (*AcquireWorkerEpochResponse)(nil), // 123: substrate.ateapi.v1.AcquireWorkerEpochResponse - (*RegisterWorkerRequest)(nil), // 124: substrate.ateapi.v1.RegisterWorkerRequest - (*RegisterWorkerResponse)(nil), // 125: substrate.ateapi.v1.RegisterWorkerResponse - (*SetWorkerSandboxRuntimesRequest)(nil), // 126: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest - (*SetWorkerSandboxRuntimesResponse)(nil), // 127: substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse - (*MintWorkerActorCertificateRequest)(nil), // 128: substrate.ateapi.v1.MintWorkerActorCertificateRequest - (*MintWorkerActorCertificateResponse)(nil), // 129: substrate.ateapi.v1.MintWorkerActorCertificateResponse - (*MintWorkerActorJwtRequest)(nil), // 130: substrate.ateapi.v1.MintWorkerActorJwtRequest - (*MintWorkerActorJwtResponse)(nil), // 131: substrate.ateapi.v1.MintWorkerActorJwtResponse - (*RequestActorSuspendRequest)(nil), // 132: substrate.ateapi.v1.RequestActorSuspendRequest - (*RequestActorSuspendResponse)(nil), // 133: substrate.ateapi.v1.RequestActorSuspendResponse - (*ReportActorCrashedRequest)(nil), // 134: substrate.ateapi.v1.ReportActorCrashedRequest - (*ReportActorCrashedResponse)(nil), // 135: substrate.ateapi.v1.ReportActorCrashedResponse - (*ReportActorSnapshotStateRequest)(nil), // 136: substrate.ateapi.v1.ReportActorSnapshotStateRequest - (*ReportActorSnapshotStateResponse)(nil), // 137: substrate.ateapi.v1.ReportActorSnapshotStateResponse - (*ActorSnapshotState)(nil), // 138: substrate.ateapi.v1.ActorSnapshotState - (*SnapshotReport)(nil), // 139: substrate.ateapi.v1.SnapshotReport - (*AccessPolicy)(nil), // 140: substrate.ateapi.v1.AccessPolicy - (*Binding)(nil), // 141: substrate.ateapi.v1.Binding - (*GetGlobalAccessPolicyRequest)(nil), // 142: substrate.ateapi.v1.GetGlobalAccessPolicyRequest - (*CreateGlobalAccessPolicyRequest)(nil), // 143: substrate.ateapi.v1.CreateGlobalAccessPolicyRequest - (*UpdateGlobalAccessPolicyRequest)(nil), // 144: substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest - (*GetAtespaceAccessPolicyRequest)(nil), // 145: substrate.ateapi.v1.GetAtespaceAccessPolicyRequest - (*CreateAtespaceAccessPolicyRequest)(nil), // 146: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest - (*UpdateAtespaceAccessPolicyRequest)(nil), // 147: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest - (*DeleteAtespaceAccessPolicyRequest)(nil), // 148: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest - (*ResourceAnnotation)(nil), // 149: substrate.ateapi.v1.ResourceAnnotation - (*MethodAnnotation)(nil), // 150: substrate.ateapi.v1.MethodAnnotation - nil, // 151: substrate.ateapi.v1.Selector.MatchLabelsEntry - nil, // 152: substrate.ateapi.v1.ExternalVolumeStatus.VolumeContextEntry - nil, // 153: substrate.ateapi.v1.ExternalVolumeClass.ParametersEntry - nil, // 154: substrate.ateapi.v1.Worker.LabelsEntry - (*timestamppb.Timestamp)(nil), // 155: google.protobuf.Timestamp - (*descriptorpb.MessageOptions)(nil), // 156: google.protobuf.MessageOptions - (*descriptorpb.MethodOptions)(nil), // 157: google.protobuf.MethodOptions + (*CreateExternalVolumeClassRequest)(nil), // 66: substrate.ateapi.v1.CreateExternalVolumeClassRequest + (*GetExternalVolumeClassRequest)(nil), // 67: substrate.ateapi.v1.GetExternalVolumeClassRequest + (*ListExternalVolumeClassesRequest)(nil), // 68: substrate.ateapi.v1.ListExternalVolumeClassesRequest + (*ListExternalVolumeClassesResponse)(nil), // 69: substrate.ateapi.v1.ListExternalVolumeClassesResponse + (*DeleteExternalVolumeClassRequest)(nil), // 70: substrate.ateapi.v1.DeleteExternalVolumeClassRequest + (*CreateActorTemplateRequest)(nil), // 71: substrate.ateapi.v1.CreateActorTemplateRequest + (*GetActorTemplateRequest)(nil), // 72: substrate.ateapi.v1.GetActorTemplateRequest + (*ListActorTemplatesRequest)(nil), // 73: substrate.ateapi.v1.ListActorTemplatesRequest + (*ListActorTemplatesResponse)(nil), // 74: substrate.ateapi.v1.ListActorTemplatesResponse + (*DeleteActorTemplateRequest)(nil), // 75: substrate.ateapi.v1.DeleteActorTemplateRequest + (*GetActorRequest)(nil), // 76: substrate.ateapi.v1.GetActorRequest + (*CreateActorRequest)(nil), // 77: substrate.ateapi.v1.CreateActorRequest + (*UpdateActorRequest)(nil), // 78: substrate.ateapi.v1.UpdateActorRequest + (*SuspendActorRequest)(nil), // 79: substrate.ateapi.v1.SuspendActorRequest + (*SuspendActorResponse)(nil), // 80: substrate.ateapi.v1.SuspendActorResponse + (*SuspendOptions)(nil), // 81: substrate.ateapi.v1.SuspendOptions + (*ResumeActorRequest)(nil), // 82: substrate.ateapi.v1.ResumeActorRequest + (*ResumeActorResponse)(nil), // 83: substrate.ateapi.v1.ResumeActorResponse + (*RevertActorRequest)(nil), // 84: substrate.ateapi.v1.RevertActorRequest + (*RevertActorResponse)(nil), // 85: substrate.ateapi.v1.RevertActorResponse + (*DeleteActorRequest)(nil), // 86: substrate.ateapi.v1.DeleteActorRequest + (*GetActorEgressPolicyRequest)(nil), // 87: substrate.ateapi.v1.GetActorEgressPolicyRequest + (*CreateActorEgressPolicyRequest)(nil), // 88: substrate.ateapi.v1.CreateActorEgressPolicyRequest + (*UpdateActorEgressPolicyRequest)(nil), // 89: substrate.ateapi.v1.UpdateActorEgressPolicyRequest + (*DeleteActorEgressPolicyRequest)(nil), // 90: substrate.ateapi.v1.DeleteActorEgressPolicyRequest + (*GetTagRequest)(nil), // 91: substrate.ateapi.v1.GetTagRequest + (*MintActorJwtRequest)(nil), // 92: substrate.ateapi.v1.MintActorJwtRequest + (*MintActorJwtResponse)(nil), // 93: substrate.ateapi.v1.MintActorJwtResponse + (*ListTagsRequest)(nil), // 94: substrate.ateapi.v1.ListTagsRequest + (*ListTagsResponse)(nil), // 95: substrate.ateapi.v1.ListTagsResponse + (*CreateTagRequest)(nil), // 96: substrate.ateapi.v1.CreateTagRequest + (*UpdateTagRequest)(nil), // 97: substrate.ateapi.v1.UpdateTagRequest + (*DeleteTagRequest)(nil), // 98: substrate.ateapi.v1.DeleteTagRequest + (*DeleteOptions)(nil), // 99: substrate.ateapi.v1.DeleteOptions + (*ListOptions)(nil), // 100: substrate.ateapi.v1.ListOptions + (*ListWorkerActorAssignmentsRequest)(nil), // 101: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest + (*ListWorkerActorAssignmentsResponse)(nil), // 102: substrate.ateapi.v1.ListWorkerActorAssignmentsResponse + (*ListWorkersRequest)(nil), // 103: substrate.ateapi.v1.ListWorkersRequest + (*ListWorkersResponse)(nil), // 104: substrate.ateapi.v1.ListWorkersResponse + (*GetWorkerRequest)(nil), // 105: substrate.ateapi.v1.GetWorkerRequest + (*CreateWorkerRequest)(nil), // 106: substrate.ateapi.v1.CreateWorkerRequest + (*UpdateWorkerRequest)(nil), // 107: substrate.ateapi.v1.UpdateWorkerRequest + (*DeleteWorkerRequest)(nil), // 108: substrate.ateapi.v1.DeleteWorkerRequest + (*DrainWorkerRequest)(nil), // 109: substrate.ateapi.v1.DrainWorkerRequest + (*DrainWorkerResponse)(nil), // 110: substrate.ateapi.v1.DrainWorkerResponse + (*MarkWorkerAvailableRequest)(nil), // 111: substrate.ateapi.v1.MarkWorkerAvailableRequest + (*MarkWorkerAvailableResponse)(nil), // 112: substrate.ateapi.v1.MarkWorkerAvailableResponse + (*MarkWorkerUnavailableRequest)(nil), // 113: substrate.ateapi.v1.MarkWorkerUnavailableRequest + (*MarkWorkerUnavailableResponse)(nil), // 114: substrate.ateapi.v1.MarkWorkerUnavailableResponse + (*ListActorsRequest)(nil), // 115: substrate.ateapi.v1.ListActorsRequest + (*ListActorsResponse)(nil), // 116: substrate.ateapi.v1.ListActorsResponse + (*Worker)(nil), // 117: substrate.ateapi.v1.Worker + (*WorkerStatus)(nil), // 118: substrate.ateapi.v1.WorkerStatus + (*WorkerSandboxClass)(nil), // 119: substrate.ateapi.v1.WorkerSandboxClass + (*WorkerSandboxRuntime)(nil), // 120: substrate.ateapi.v1.WorkerSandboxRuntime + (*RuntimeOverhead)(nil), // 121: substrate.ateapi.v1.RuntimeOverhead + (*ActorSandboxRuntime)(nil), // 122: substrate.ateapi.v1.ActorSandboxRuntime + (*VersionedSandboxCompat)(nil), // 123: substrate.ateapi.v1.VersionedSandboxCompat + (*AttributeEntry)(nil), // 124: substrate.ateapi.v1.AttributeEntry + (*WorkerResources)(nil), // 125: substrate.ateapi.v1.WorkerResources + (*ActorAssignment)(nil), // 126: substrate.ateapi.v1.ActorAssignment + (*AcquireWorkerEpochRequest)(nil), // 127: substrate.ateapi.v1.AcquireWorkerEpochRequest + (*AcquireWorkerEpochResponse)(nil), // 128: substrate.ateapi.v1.AcquireWorkerEpochResponse + (*RegisterWorkerRequest)(nil), // 129: substrate.ateapi.v1.RegisterWorkerRequest + (*RegisterWorkerResponse)(nil), // 130: substrate.ateapi.v1.RegisterWorkerResponse + (*SetWorkerSandboxRuntimesRequest)(nil), // 131: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest + (*SetWorkerSandboxRuntimesResponse)(nil), // 132: substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse + (*MintWorkerActorCertificateRequest)(nil), // 133: substrate.ateapi.v1.MintWorkerActorCertificateRequest + (*MintWorkerActorCertificateResponse)(nil), // 134: substrate.ateapi.v1.MintWorkerActorCertificateResponse + (*MintWorkerActorJwtRequest)(nil), // 135: substrate.ateapi.v1.MintWorkerActorJwtRequest + (*MintWorkerActorJwtResponse)(nil), // 136: substrate.ateapi.v1.MintWorkerActorJwtResponse + (*RequestActorSuspendRequest)(nil), // 137: substrate.ateapi.v1.RequestActorSuspendRequest + (*RequestActorSuspendResponse)(nil), // 138: substrate.ateapi.v1.RequestActorSuspendResponse + (*ReportActorCrashedRequest)(nil), // 139: substrate.ateapi.v1.ReportActorCrashedRequest + (*ReportActorCrashedResponse)(nil), // 140: substrate.ateapi.v1.ReportActorCrashedResponse + (*ReportActorSnapshotStateRequest)(nil), // 141: substrate.ateapi.v1.ReportActorSnapshotStateRequest + (*ReportActorSnapshotStateResponse)(nil), // 142: substrate.ateapi.v1.ReportActorSnapshotStateResponse + (*ActorSnapshotState)(nil), // 143: substrate.ateapi.v1.ActorSnapshotState + (*SnapshotReport)(nil), // 144: substrate.ateapi.v1.SnapshotReport + (*AccessPolicy)(nil), // 145: substrate.ateapi.v1.AccessPolicy + (*Binding)(nil), // 146: substrate.ateapi.v1.Binding + (*GetGlobalAccessPolicyRequest)(nil), // 147: substrate.ateapi.v1.GetGlobalAccessPolicyRequest + (*CreateGlobalAccessPolicyRequest)(nil), // 148: substrate.ateapi.v1.CreateGlobalAccessPolicyRequest + (*UpdateGlobalAccessPolicyRequest)(nil), // 149: substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest + (*GetAtespaceAccessPolicyRequest)(nil), // 150: substrate.ateapi.v1.GetAtespaceAccessPolicyRequest + (*CreateAtespaceAccessPolicyRequest)(nil), // 151: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest + (*UpdateAtespaceAccessPolicyRequest)(nil), // 152: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest + (*DeleteAtespaceAccessPolicyRequest)(nil), // 153: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest + (*ResourceAnnotation)(nil), // 154: substrate.ateapi.v1.ResourceAnnotation + (*MethodAnnotation)(nil), // 155: substrate.ateapi.v1.MethodAnnotation + nil, // 156: substrate.ateapi.v1.Selector.MatchLabelsEntry + nil, // 157: substrate.ateapi.v1.ExternalVolumeStatus.VolumeContextEntry + nil, // 158: substrate.ateapi.v1.ExternalVolumeClass.ParametersEntry + nil, // 159: substrate.ateapi.v1.Worker.LabelsEntry + (*timestamppb.Timestamp)(nil), // 160: google.protobuf.Timestamp + (*descriptorpb.MessageOptions)(nil), // 161: google.protobuf.MessageOptions + (*descriptorpb.MethodOptions)(nil), // 162: google.protobuf.MethodOptions } var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 1, // 0: substrate.ateapi.v1.SnapshotStorage.state:type_name -> substrate.ateapi.v1.SnapshotStorageState @@ -10921,13 +11209,13 @@ var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 0, // 2: substrate.ateapi.v1.Snapshot.owner:type_name -> substrate.ateapi.v1.SnapshotOwner 2, // 3: substrate.ateapi.v1.Snapshot.fidelity:type_name -> substrate.ateapi.v1.SnapshotFidelity 11, // 4: substrate.ateapi.v1.Snapshot.durable_snapshot:type_name -> substrate.ateapi.v1.SnapshotStorage - 117, // 5: substrate.ateapi.v1.Snapshot.sandbox_runtime:type_name -> substrate.ateapi.v1.ActorSandboxRuntime - 151, // 6: substrate.ateapi.v1.Selector.match_labels:type_name -> substrate.ateapi.v1.Selector.MatchLabelsEntry - 155, // 7: substrate.ateapi.v1.ResourceMetadata.create_time:type_name -> google.protobuf.Timestamp - 155, // 8: substrate.ateapi.v1.ResourceMetadata.update_time:type_name -> google.protobuf.Timestamp - 155, // 9: substrate.ateapi.v1.ResourceMetadata.delete_time:type_name -> google.protobuf.Timestamp + 122, // 5: substrate.ateapi.v1.Snapshot.sandbox_runtime:type_name -> substrate.ateapi.v1.ActorSandboxRuntime + 156, // 6: substrate.ateapi.v1.Selector.match_labels:type_name -> substrate.ateapi.v1.Selector.MatchLabelsEntry + 160, // 7: substrate.ateapi.v1.ResourceMetadata.create_time:type_name -> google.protobuf.Timestamp + 160, // 8: substrate.ateapi.v1.ResourceMetadata.update_time:type_name -> google.protobuf.Timestamp + 160, // 9: substrate.ateapi.v1.ResourceMetadata.delete_time:type_name -> google.protobuf.Timestamp 16, // 10: substrate.ateapi.v1.ExternalVolumes.volumes:type_name -> substrate.ateapi.v1.ExternalVolumeStatus - 152, // 11: substrate.ateapi.v1.ExternalVolumeStatus.volume_context:type_name -> substrate.ateapi.v1.ExternalVolumeStatus.VolumeContextEntry + 157, // 11: substrate.ateapi.v1.ExternalVolumeStatus.volume_context:type_name -> substrate.ateapi.v1.ExternalVolumeStatus.VolumeContextEntry 14, // 12: substrate.ateapi.v1.Actor.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata 35, // 13: substrate.ateapi.v1.Actor.actor_template:type_name -> substrate.ateapi.v1.ObjectRef 13, // 14: substrate.ateapi.v1.Actor.worker_selector:type_name -> substrate.ateapi.v1.Selector @@ -10952,9 +11240,9 @@ var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 15, // 33: substrate.ateapi.v1.ActorStatus.external_volumes:type_name -> substrate.ateapi.v1.ExternalVolumes 30, // 34: substrate.ateapi.v1.ActorStatus.crash:type_name -> substrate.ateapi.v1.ActorCrash 12, // 35: substrate.ateapi.v1.ActorStatus.snapshots:type_name -> substrate.ateapi.v1.Snapshot - 155, // 36: substrate.ateapi.v1.ActorCrash.crash_time:type_name -> google.protobuf.Timestamp + 160, // 36: substrate.ateapi.v1.ActorCrash.crash_time:type_name -> google.protobuf.Timestamp 35, // 37: substrate.ateapi.v1.WorkerAssignment.worker:type_name -> substrate.ateapi.v1.ObjectRef - 117, // 38: substrate.ateapi.v1.WorkerAssignment.sandbox_runtime:type_name -> substrate.ateapi.v1.ActorSandboxRuntime + 122, // 38: substrate.ateapi.v1.WorkerAssignment.sandbox_runtime:type_name -> substrate.ateapi.v1.ActorSandboxRuntime 12, // 39: substrate.ateapi.v1.TagStatus.snapshot:type_name -> substrate.ateapi.v1.Snapshot 14, // 40: substrate.ateapi.v1.Tag.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata 32, // 41: substrate.ateapi.v1.Tag.status:type_name -> substrate.ateapi.v1.TagStatus @@ -10971,7 +11259,7 @@ var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 40, // 52: substrate.ateapi.v1.ActorTemplate.status:type_name -> substrate.ateapi.v1.ActorTemplateStatus 38, // 53: substrate.ateapi.v1.ResourceRequirements.limits:type_name -> substrate.ateapi.v1.Resources 35, // 54: substrate.ateapi.v1.GoldenSnapshotStatus.golden_tag:type_name -> substrate.ateapi.v1.ObjectRef - 155, // 55: substrate.ateapi.v1.GoldenSnapshotStatus.snapshot_time:type_name -> google.protobuf.Timestamp + 160, // 55: substrate.ateapi.v1.GoldenSnapshotStatus.snapshot_time:type_name -> google.protobuf.Timestamp 39, // 56: substrate.ateapi.v1.ActorTemplateStatus.golden_snapshot_status:type_name -> substrate.ateapi.v1.GoldenSnapshotStatus 2, // 57: substrate.ateapi.v1.SnapshotConfig.preferred_fidelity:type_name -> substrate.ateapi.v1.SnapshotFidelity 42, // 58: substrate.ateapi.v1.SnapshotConfig.golden_snapshot_config:type_name -> substrate.ateapi.v1.GoldenSnapshotConfig @@ -10989,7 +11277,7 @@ var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 51, // 70: substrate.ateapi.v1.Volume.image:type_name -> substrate.ateapi.v1.ImageVolumeSource 53, // 71: substrate.ateapi.v1.ExternalVolumeSource.template:type_name -> substrate.ateapi.v1.ExternalVolumeTemplate 14, // 72: substrate.ateapi.v1.ExternalVolumeClass.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata - 153, // 73: substrate.ateapi.v1.ExternalVolumeClass.parameters:type_name -> substrate.ateapi.v1.ExternalVolumeClass.ParametersEntry + 158, // 73: substrate.ateapi.v1.ExternalVolumeClass.parameters:type_name -> substrate.ateapi.v1.ExternalVolumeClass.ParametersEntry 56, // 74: substrate.ateapi.v1.SystemInfoVolumeSource.data_sources:type_name -> substrate.ateapi.v1.SystemInfoDataSource 57, // 75: substrate.ateapi.v1.SystemInfoDataSource.actor_metadata:type_name -> substrate.ateapi.v1.ActorMetadataDataSource 59, // 76: substrate.ateapi.v1.SystemInfoDataSource.trust_bundle:type_name -> substrate.ateapi.v1.TrustBundleDataSource @@ -10997,227 +11285,241 @@ var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 6, // 78: substrate.ateapi.v1.ActorMetadataItem.field:type_name -> substrate.ateapi.v1.ActorMetadataField 34, // 79: substrate.ateapi.v1.CreateAtespaceRequest.atespace:type_name -> substrate.ateapi.v1.Atespace 35, // 80: substrate.ateapi.v1.GetAtespaceRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef - 95, // 81: substrate.ateapi.v1.ListAtespacesRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 100, // 81: substrate.ateapi.v1.ListAtespacesRequest.options:type_name -> substrate.ateapi.v1.ListOptions 34, // 82: substrate.ateapi.v1.ListAtespacesResponse.atespaces:type_name -> substrate.ateapi.v1.Atespace 35, // 83: substrate.ateapi.v1.DeleteAtespaceRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef - 94, // 84: substrate.ateapi.v1.DeleteAtespaceRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions - 36, // 85: substrate.ateapi.v1.CreateActorTemplateRequest.actor_template:type_name -> substrate.ateapi.v1.ActorTemplate - 35, // 86: substrate.ateapi.v1.GetActorTemplateRequest.actor_template:type_name -> substrate.ateapi.v1.ObjectRef - 95, // 87: substrate.ateapi.v1.ListActorTemplatesRequest.options:type_name -> substrate.ateapi.v1.ListOptions - 36, // 88: substrate.ateapi.v1.ListActorTemplatesResponse.actor_templates:type_name -> substrate.ateapi.v1.ActorTemplate - 35, // 89: substrate.ateapi.v1.DeleteActorTemplateRequest.actor_template:type_name -> substrate.ateapi.v1.ObjectRef - 94, // 90: substrate.ateapi.v1.DeleteActorTemplateRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions - 35, // 91: substrate.ateapi.v1.GetActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 17, // 92: substrate.ateapi.v1.CreateActorRequest.actor:type_name -> substrate.ateapi.v1.Actor - 17, // 93: substrate.ateapi.v1.UpdateActorRequest.actor:type_name -> substrate.ateapi.v1.Actor - 35, // 94: substrate.ateapi.v1.SuspendActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 76, // 95: substrate.ateapi.v1.SuspendActorRequest.options:type_name -> substrate.ateapi.v1.SuspendOptions - 17, // 96: substrate.ateapi.v1.SuspendActorResponse.actor:type_name -> substrate.ateapi.v1.Actor - 7, // 97: substrate.ateapi.v1.SuspendOptions.mode:type_name -> substrate.ateapi.v1.DurabilityMode - 35, // 98: substrate.ateapi.v1.ResumeActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 17, // 99: substrate.ateapi.v1.ResumeActorResponse.actor:type_name -> substrate.ateapi.v1.Actor - 35, // 100: substrate.ateapi.v1.RevertActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 17, // 101: substrate.ateapi.v1.RevertActorResponse.actor:type_name -> substrate.ateapi.v1.Actor - 35, // 102: substrate.ateapi.v1.DeleteActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 94, // 103: substrate.ateapi.v1.DeleteActorRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions - 35, // 104: substrate.ateapi.v1.GetActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 105: substrate.ateapi.v1.CreateActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 18, // 106: substrate.ateapi.v1.CreateActorEgressPolicyRequest.egress_policy:type_name -> substrate.ateapi.v1.EgressPolicy - 35, // 107: substrate.ateapi.v1.UpdateActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 18, // 108: substrate.ateapi.v1.UpdateActorEgressPolicyRequest.egress_policy:type_name -> substrate.ateapi.v1.EgressPolicy - 35, // 109: substrate.ateapi.v1.DeleteActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 94, // 110: substrate.ateapi.v1.DeleteActorEgressPolicyRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions - 35, // 111: substrate.ateapi.v1.GetTagRequest.tag:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 112: substrate.ateapi.v1.MintActorJwtRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 155, // 113: substrate.ateapi.v1.MintActorJwtResponse.expire_time:type_name -> google.protobuf.Timestamp - 95, // 114: substrate.ateapi.v1.ListTagsRequest.options:type_name -> substrate.ateapi.v1.ListOptions - 33, // 115: substrate.ateapi.v1.ListTagsResponse.tags:type_name -> substrate.ateapi.v1.Tag - 33, // 116: substrate.ateapi.v1.CreateTagRequest.tag:type_name -> substrate.ateapi.v1.Tag - 33, // 117: substrate.ateapi.v1.UpdateTagRequest.tag:type_name -> substrate.ateapi.v1.Tag - 35, // 118: substrate.ateapi.v1.DeleteTagRequest.tag:type_name -> substrate.ateapi.v1.ObjectRef - 94, // 119: substrate.ateapi.v1.DeleteTagRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions - 35, // 120: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 95, // 121: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest.options:type_name -> substrate.ateapi.v1.ListOptions - 121, // 122: substrate.ateapi.v1.ListWorkerActorAssignmentsResponse.actor_assignments:type_name -> substrate.ateapi.v1.ActorAssignment - 95, // 123: substrate.ateapi.v1.ListWorkersRequest.options:type_name -> substrate.ateapi.v1.ListOptions - 112, // 124: substrate.ateapi.v1.ListWorkersResponse.workers:type_name -> substrate.ateapi.v1.Worker - 35, // 125: substrate.ateapi.v1.GetWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 112, // 126: substrate.ateapi.v1.CreateWorkerRequest.worker:type_name -> substrate.ateapi.v1.Worker - 112, // 127: substrate.ateapi.v1.UpdateWorkerRequest.worker:type_name -> substrate.ateapi.v1.Worker - 35, // 128: substrate.ateapi.v1.DeleteWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 94, // 129: substrate.ateapi.v1.DeleteWorkerRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions - 35, // 130: substrate.ateapi.v1.DrainWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 112, // 131: substrate.ateapi.v1.DrainWorkerResponse.worker:type_name -> substrate.ateapi.v1.Worker - 35, // 132: substrate.ateapi.v1.MarkWorkerAvailableRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 112, // 133: substrate.ateapi.v1.MarkWorkerAvailableResponse.worker:type_name -> substrate.ateapi.v1.Worker - 35, // 134: substrate.ateapi.v1.MarkWorkerUnavailableRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 112, // 135: substrate.ateapi.v1.MarkWorkerUnavailableResponse.worker:type_name -> substrate.ateapi.v1.Worker - 95, // 136: substrate.ateapi.v1.ListActorsRequest.options:type_name -> substrate.ateapi.v1.ListOptions - 17, // 137: substrate.ateapi.v1.ListActorsResponse.actors:type_name -> substrate.ateapi.v1.Actor - 14, // 138: substrate.ateapi.v1.Worker.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata - 154, // 139: substrate.ateapi.v1.Worker.labels:type_name -> substrate.ateapi.v1.Worker.LabelsEntry - 113, // 140: substrate.ateapi.v1.Worker.status:type_name -> substrate.ateapi.v1.WorkerStatus - 8, // 141: substrate.ateapi.v1.WorkerStatus.state:type_name -> substrate.ateapi.v1.WorkerState - 120, // 142: substrate.ateapi.v1.WorkerStatus.capacity:type_name -> substrate.ateapi.v1.WorkerResources - 120, // 143: substrate.ateapi.v1.WorkerStatus.allocated:type_name -> substrate.ateapi.v1.WorkerResources - 114, // 144: substrate.ateapi.v1.WorkerStatus.sandbox_classes:type_name -> substrate.ateapi.v1.WorkerSandboxClass - 115, // 145: substrate.ateapi.v1.WorkerSandboxClass.default_runtime:type_name -> substrate.ateapi.v1.WorkerSandboxRuntime - 115, // 146: substrate.ateapi.v1.WorkerSandboxClass.restorable_runtimes:type_name -> substrate.ateapi.v1.WorkerSandboxRuntime - 118, // 147: substrate.ateapi.v1.WorkerSandboxRuntime.version:type_name -> substrate.ateapi.v1.VersionedSandboxCompat - 116, // 148: substrate.ateapi.v1.WorkerSandboxRuntime.actor_overhead:type_name -> substrate.ateapi.v1.RuntimeOverhead - 118, // 149: substrate.ateapi.v1.ActorSandboxRuntime.version:type_name -> substrate.ateapi.v1.VersionedSandboxCompat - 119, // 150: substrate.ateapi.v1.VersionedSandboxCompat.attributes:type_name -> substrate.ateapi.v1.AttributeEntry - 14, // 151: substrate.ateapi.v1.ActorAssignment.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata - 35, // 152: substrate.ateapi.v1.ActorAssignment.actor:type_name -> substrate.ateapi.v1.ObjectRef - 38, // 153: substrate.ateapi.v1.ActorAssignment.resources:type_name -> substrate.ateapi.v1.Resources - 35, // 154: substrate.ateapi.v1.AcquireWorkerEpochRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 155: substrate.ateapi.v1.RegisterWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 120, // 156: substrate.ateapi.v1.RegisterWorkerRequest.capacity:type_name -> substrate.ateapi.v1.WorkerResources - 112, // 157: substrate.ateapi.v1.RegisterWorkerResponse.worker:type_name -> substrate.ateapi.v1.Worker - 35, // 158: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 114, // 159: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest.sandbox_classes:type_name -> substrate.ateapi.v1.WorkerSandboxClass - 112, // 160: substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse.worker:type_name -> substrate.ateapi.v1.Worker - 35, // 161: substrate.ateapi.v1.MintWorkerActorCertificateRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 162: substrate.ateapi.v1.MintWorkerActorCertificateRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 163: substrate.ateapi.v1.MintWorkerActorJwtRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 155, // 164: substrate.ateapi.v1.MintWorkerActorJwtResponse.expire_time:type_name -> google.protobuf.Timestamp - 35, // 165: substrate.ateapi.v1.RequestActorSuspendRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 166: substrate.ateapi.v1.RequestActorSuspendRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 17, // 167: substrate.ateapi.v1.RequestActorSuspendResponse.actor:type_name -> substrate.ateapi.v1.Actor - 35, // 168: substrate.ateapi.v1.ReportActorCrashedRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 169: substrate.ateapi.v1.ReportActorCrashedRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 17, // 170: substrate.ateapi.v1.ReportActorCrashedResponse.actor:type_name -> substrate.ateapi.v1.Actor - 35, // 171: substrate.ateapi.v1.ReportActorSnapshotStateRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 138, // 172: substrate.ateapi.v1.ReportActorSnapshotStateRequest.state:type_name -> substrate.ateapi.v1.ActorSnapshotState - 139, // 173: substrate.ateapi.v1.ActorSnapshotState.latest_local:type_name -> substrate.ateapi.v1.SnapshotReport - 139, // 174: substrate.ateapi.v1.ActorSnapshotState.uploading:type_name -> substrate.ateapi.v1.SnapshotReport - 139, // 175: substrate.ateapi.v1.ActorSnapshotState.latest_durable:type_name -> substrate.ateapi.v1.SnapshotReport - 155, // 176: substrate.ateapi.v1.ActorSnapshotState.upload_due_time:type_name -> google.protobuf.Timestamp - 2, // 177: substrate.ateapi.v1.SnapshotReport.fidelity:type_name -> substrate.ateapi.v1.SnapshotFidelity - 10, // 178: substrate.ateapi.v1.SnapshotReport.object:type_name -> substrate.ateapi.v1.ObjectSnapshot - 155, // 179: substrate.ateapi.v1.SnapshotReport.local_commit_time:type_name -> google.protobuf.Timestamp - 155, // 180: substrate.ateapi.v1.SnapshotReport.durable_complete_time:type_name -> google.protobuf.Timestamp - 14, // 181: substrate.ateapi.v1.AccessPolicy.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata - 141, // 182: substrate.ateapi.v1.AccessPolicy.bindings:type_name -> substrate.ateapi.v1.Binding - 140, // 183: substrate.ateapi.v1.CreateGlobalAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy - 140, // 184: substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy - 35, // 185: substrate.ateapi.v1.GetAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 186: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef - 140, // 187: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy - 35, // 188: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef - 140, // 189: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy - 35, // 190: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef - 94, // 191: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions - 9, // 192: substrate.ateapi.v1.ResourceAnnotation.scope:type_name -> substrate.ateapi.v1.Scope - 156, // 193: substrate.ateapi.v1.resource:extendee -> google.protobuf.MessageOptions - 157, // 194: substrate.ateapi.v1.method:extendee -> google.protobuf.MethodOptions - 149, // 195: substrate.ateapi.v1.resource:type_name -> substrate.ateapi.v1.ResourceAnnotation - 150, // 196: substrate.ateapi.v1.method:type_name -> substrate.ateapi.v1.MethodAnnotation - 71, // 197: substrate.ateapi.v1.Control.GetActor:input_type -> substrate.ateapi.v1.GetActorRequest - 72, // 198: substrate.ateapi.v1.Control.CreateActor:input_type -> substrate.ateapi.v1.CreateActorRequest - 73, // 199: substrate.ateapi.v1.Control.UpdateActor:input_type -> substrate.ateapi.v1.UpdateActorRequest - 74, // 200: substrate.ateapi.v1.Control.SuspendActor:input_type -> substrate.ateapi.v1.SuspendActorRequest - 77, // 201: substrate.ateapi.v1.Control.ResumeActor:input_type -> substrate.ateapi.v1.ResumeActorRequest - 79, // 202: substrate.ateapi.v1.Control.RevertActor:input_type -> substrate.ateapi.v1.RevertActorRequest - 81, // 203: substrate.ateapi.v1.Control.DeleteActor:input_type -> substrate.ateapi.v1.DeleteActorRequest - 82, // 204: substrate.ateapi.v1.Control.GetActorEgressPolicy:input_type -> substrate.ateapi.v1.GetActorEgressPolicyRequest - 83, // 205: substrate.ateapi.v1.Control.CreateActorEgressPolicy:input_type -> substrate.ateapi.v1.CreateActorEgressPolicyRequest - 84, // 206: substrate.ateapi.v1.Control.UpdateActorEgressPolicy:input_type -> substrate.ateapi.v1.UpdateActorEgressPolicyRequest - 85, // 207: substrate.ateapi.v1.Control.DeleteActorEgressPolicy:input_type -> substrate.ateapi.v1.DeleteActorEgressPolicyRequest - 87, // 208: substrate.ateapi.v1.Control.MintActorJwt:input_type -> substrate.ateapi.v1.MintActorJwtRequest - 91, // 209: substrate.ateapi.v1.Control.CreateTag:input_type -> substrate.ateapi.v1.CreateTagRequest - 86, // 210: substrate.ateapi.v1.Control.GetTag:input_type -> substrate.ateapi.v1.GetTagRequest - 89, // 211: substrate.ateapi.v1.Control.ListTags:input_type -> substrate.ateapi.v1.ListTagsRequest - 92, // 212: substrate.ateapi.v1.Control.UpdateTag:input_type -> substrate.ateapi.v1.UpdateTagRequest - 93, // 213: substrate.ateapi.v1.Control.DeleteTag:input_type -> substrate.ateapi.v1.DeleteTagRequest - 98, // 214: substrate.ateapi.v1.Control.ListWorkers:input_type -> substrate.ateapi.v1.ListWorkersRequest - 100, // 215: substrate.ateapi.v1.Control.GetWorker:input_type -> substrate.ateapi.v1.GetWorkerRequest - 101, // 216: substrate.ateapi.v1.Control.CreateWorker:input_type -> substrate.ateapi.v1.CreateWorkerRequest - 102, // 217: substrate.ateapi.v1.Control.UpdateWorker:input_type -> substrate.ateapi.v1.UpdateWorkerRequest - 103, // 218: substrate.ateapi.v1.Control.DeleteWorker:input_type -> substrate.ateapi.v1.DeleteWorkerRequest - 104, // 219: substrate.ateapi.v1.Control.DrainWorker:input_type -> substrate.ateapi.v1.DrainWorkerRequest - 106, // 220: substrate.ateapi.v1.Control.MarkWorkerAvailable:input_type -> substrate.ateapi.v1.MarkWorkerAvailableRequest - 108, // 221: substrate.ateapi.v1.Control.MarkWorkerUnavailable:input_type -> substrate.ateapi.v1.MarkWorkerUnavailableRequest - 96, // 222: substrate.ateapi.v1.Control.ListWorkerActorAssignments:input_type -> substrate.ateapi.v1.ListWorkerActorAssignmentsRequest - 110, // 223: substrate.ateapi.v1.Control.ListActors:input_type -> substrate.ateapi.v1.ListActorsRequest - 61, // 224: substrate.ateapi.v1.Control.CreateAtespace:input_type -> substrate.ateapi.v1.CreateAtespaceRequest - 62, // 225: substrate.ateapi.v1.Control.GetAtespace:input_type -> substrate.ateapi.v1.GetAtespaceRequest - 63, // 226: substrate.ateapi.v1.Control.ListAtespaces:input_type -> substrate.ateapi.v1.ListAtespacesRequest - 65, // 227: substrate.ateapi.v1.Control.DeleteAtespace:input_type -> substrate.ateapi.v1.DeleteAtespaceRequest - 66, // 228: substrate.ateapi.v1.Control.CreateActorTemplate:input_type -> substrate.ateapi.v1.CreateActorTemplateRequest - 67, // 229: substrate.ateapi.v1.Control.GetActorTemplate:input_type -> substrate.ateapi.v1.GetActorTemplateRequest - 68, // 230: substrate.ateapi.v1.Control.ListActorTemplates:input_type -> substrate.ateapi.v1.ListActorTemplatesRequest - 70, // 231: substrate.ateapi.v1.Control.DeleteActorTemplate:input_type -> substrate.ateapi.v1.DeleteActorTemplateRequest - 142, // 232: substrate.ateapi.v1.Control.GetGlobalAccessPolicy:input_type -> substrate.ateapi.v1.GetGlobalAccessPolicyRequest - 143, // 233: substrate.ateapi.v1.Control.CreateGlobalAccessPolicy:input_type -> substrate.ateapi.v1.CreateGlobalAccessPolicyRequest - 144, // 234: substrate.ateapi.v1.Control.UpdateGlobalAccessPolicy:input_type -> substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest - 145, // 235: substrate.ateapi.v1.Control.GetAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.GetAtespaceAccessPolicyRequest - 146, // 236: substrate.ateapi.v1.Control.CreateAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest - 147, // 237: substrate.ateapi.v1.Control.UpdateAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest - 148, // 238: substrate.ateapi.v1.Control.DeleteAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest - 122, // 239: substrate.ateapi.v1.WorkerService.AcquireWorkerEpoch:input_type -> substrate.ateapi.v1.AcquireWorkerEpochRequest - 124, // 240: substrate.ateapi.v1.WorkerService.RegisterWorker:input_type -> substrate.ateapi.v1.RegisterWorkerRequest - 126, // 241: substrate.ateapi.v1.WorkerService.SetWorkerSandboxRuntimes:input_type -> substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest - 128, // 242: substrate.ateapi.v1.WorkerService.MintWorkerActorCertificate:input_type -> substrate.ateapi.v1.MintWorkerActorCertificateRequest - 130, // 243: substrate.ateapi.v1.WorkerService.MintWorkerActorJwt:input_type -> substrate.ateapi.v1.MintWorkerActorJwtRequest - 132, // 244: substrate.ateapi.v1.WorkerService.RequestActorSuspend:input_type -> substrate.ateapi.v1.RequestActorSuspendRequest - 136, // 245: substrate.ateapi.v1.WorkerService.ReportActorSnapshotState:input_type -> substrate.ateapi.v1.ReportActorSnapshotStateRequest - 134, // 246: substrate.ateapi.v1.WorkerService.ReportActorCrashed:input_type -> substrate.ateapi.v1.ReportActorCrashedRequest - 17, // 247: substrate.ateapi.v1.Control.GetActor:output_type -> substrate.ateapi.v1.Actor - 17, // 248: substrate.ateapi.v1.Control.CreateActor:output_type -> substrate.ateapi.v1.Actor - 17, // 249: substrate.ateapi.v1.Control.UpdateActor:output_type -> substrate.ateapi.v1.Actor - 75, // 250: substrate.ateapi.v1.Control.SuspendActor:output_type -> substrate.ateapi.v1.SuspendActorResponse - 78, // 251: substrate.ateapi.v1.Control.ResumeActor:output_type -> substrate.ateapi.v1.ResumeActorResponse - 80, // 252: substrate.ateapi.v1.Control.RevertActor:output_type -> substrate.ateapi.v1.RevertActorResponse - 17, // 253: substrate.ateapi.v1.Control.DeleteActor:output_type -> substrate.ateapi.v1.Actor - 18, // 254: substrate.ateapi.v1.Control.GetActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy - 18, // 255: substrate.ateapi.v1.Control.CreateActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy - 18, // 256: substrate.ateapi.v1.Control.UpdateActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy - 18, // 257: substrate.ateapi.v1.Control.DeleteActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy - 88, // 258: substrate.ateapi.v1.Control.MintActorJwt:output_type -> substrate.ateapi.v1.MintActorJwtResponse - 33, // 259: substrate.ateapi.v1.Control.CreateTag:output_type -> substrate.ateapi.v1.Tag - 33, // 260: substrate.ateapi.v1.Control.GetTag:output_type -> substrate.ateapi.v1.Tag - 90, // 261: substrate.ateapi.v1.Control.ListTags:output_type -> substrate.ateapi.v1.ListTagsResponse - 33, // 262: substrate.ateapi.v1.Control.UpdateTag:output_type -> substrate.ateapi.v1.Tag - 33, // 263: substrate.ateapi.v1.Control.DeleteTag:output_type -> substrate.ateapi.v1.Tag - 99, // 264: substrate.ateapi.v1.Control.ListWorkers:output_type -> substrate.ateapi.v1.ListWorkersResponse - 112, // 265: substrate.ateapi.v1.Control.GetWorker:output_type -> substrate.ateapi.v1.Worker - 112, // 266: substrate.ateapi.v1.Control.CreateWorker:output_type -> substrate.ateapi.v1.Worker - 112, // 267: substrate.ateapi.v1.Control.UpdateWorker:output_type -> substrate.ateapi.v1.Worker - 112, // 268: substrate.ateapi.v1.Control.DeleteWorker:output_type -> substrate.ateapi.v1.Worker - 105, // 269: substrate.ateapi.v1.Control.DrainWorker:output_type -> substrate.ateapi.v1.DrainWorkerResponse - 107, // 270: substrate.ateapi.v1.Control.MarkWorkerAvailable:output_type -> substrate.ateapi.v1.MarkWorkerAvailableResponse - 109, // 271: substrate.ateapi.v1.Control.MarkWorkerUnavailable:output_type -> substrate.ateapi.v1.MarkWorkerUnavailableResponse - 97, // 272: substrate.ateapi.v1.Control.ListWorkerActorAssignments:output_type -> substrate.ateapi.v1.ListWorkerActorAssignmentsResponse - 111, // 273: substrate.ateapi.v1.Control.ListActors:output_type -> substrate.ateapi.v1.ListActorsResponse - 34, // 274: substrate.ateapi.v1.Control.CreateAtespace:output_type -> substrate.ateapi.v1.Atespace - 34, // 275: substrate.ateapi.v1.Control.GetAtespace:output_type -> substrate.ateapi.v1.Atespace - 64, // 276: substrate.ateapi.v1.Control.ListAtespaces:output_type -> substrate.ateapi.v1.ListAtespacesResponse - 34, // 277: substrate.ateapi.v1.Control.DeleteAtespace:output_type -> substrate.ateapi.v1.Atespace - 36, // 278: substrate.ateapi.v1.Control.CreateActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate - 36, // 279: substrate.ateapi.v1.Control.GetActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate - 69, // 280: substrate.ateapi.v1.Control.ListActorTemplates:output_type -> substrate.ateapi.v1.ListActorTemplatesResponse - 36, // 281: substrate.ateapi.v1.Control.DeleteActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate - 140, // 282: substrate.ateapi.v1.Control.GetGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 140, // 283: substrate.ateapi.v1.Control.CreateGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 140, // 284: substrate.ateapi.v1.Control.UpdateGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 140, // 285: substrate.ateapi.v1.Control.GetAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 140, // 286: substrate.ateapi.v1.Control.CreateAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 140, // 287: substrate.ateapi.v1.Control.UpdateAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 140, // 288: substrate.ateapi.v1.Control.DeleteAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 123, // 289: substrate.ateapi.v1.WorkerService.AcquireWorkerEpoch:output_type -> substrate.ateapi.v1.AcquireWorkerEpochResponse - 125, // 290: substrate.ateapi.v1.WorkerService.RegisterWorker:output_type -> substrate.ateapi.v1.RegisterWorkerResponse - 127, // 291: substrate.ateapi.v1.WorkerService.SetWorkerSandboxRuntimes:output_type -> substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse - 129, // 292: substrate.ateapi.v1.WorkerService.MintWorkerActorCertificate:output_type -> substrate.ateapi.v1.MintWorkerActorCertificateResponse - 131, // 293: substrate.ateapi.v1.WorkerService.MintWorkerActorJwt:output_type -> substrate.ateapi.v1.MintWorkerActorJwtResponse - 133, // 294: substrate.ateapi.v1.WorkerService.RequestActorSuspend:output_type -> substrate.ateapi.v1.RequestActorSuspendResponse - 137, // 295: substrate.ateapi.v1.WorkerService.ReportActorSnapshotState:output_type -> substrate.ateapi.v1.ReportActorSnapshotStateResponse - 135, // 296: substrate.ateapi.v1.WorkerService.ReportActorCrashed:output_type -> substrate.ateapi.v1.ReportActorCrashedResponse - 247, // [247:297] is the sub-list for method output_type - 197, // [197:247] is the sub-list for method input_type - 195, // [195:197] is the sub-list for extension type_name - 193, // [193:195] is the sub-list for extension extendee - 0, // [0:193] is the sub-list for field type_name + 99, // 84: substrate.ateapi.v1.DeleteAtespaceRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 54, // 85: substrate.ateapi.v1.CreateExternalVolumeClassRequest.external_volume_class:type_name -> substrate.ateapi.v1.ExternalVolumeClass + 35, // 86: substrate.ateapi.v1.GetExternalVolumeClassRequest.external_volume_class:type_name -> substrate.ateapi.v1.ObjectRef + 100, // 87: substrate.ateapi.v1.ListExternalVolumeClassesRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 54, // 88: substrate.ateapi.v1.ListExternalVolumeClassesResponse.external_volume_classes:type_name -> substrate.ateapi.v1.ExternalVolumeClass + 35, // 89: substrate.ateapi.v1.DeleteExternalVolumeClassRequest.external_volume_class:type_name -> substrate.ateapi.v1.ObjectRef + 99, // 90: substrate.ateapi.v1.DeleteExternalVolumeClassRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 36, // 91: substrate.ateapi.v1.CreateActorTemplateRequest.actor_template:type_name -> substrate.ateapi.v1.ActorTemplate + 35, // 92: substrate.ateapi.v1.GetActorTemplateRequest.actor_template:type_name -> substrate.ateapi.v1.ObjectRef + 100, // 93: substrate.ateapi.v1.ListActorTemplatesRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 36, // 94: substrate.ateapi.v1.ListActorTemplatesResponse.actor_templates:type_name -> substrate.ateapi.v1.ActorTemplate + 35, // 95: substrate.ateapi.v1.DeleteActorTemplateRequest.actor_template:type_name -> substrate.ateapi.v1.ObjectRef + 99, // 96: substrate.ateapi.v1.DeleteActorTemplateRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 35, // 97: substrate.ateapi.v1.GetActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 17, // 98: substrate.ateapi.v1.CreateActorRequest.actor:type_name -> substrate.ateapi.v1.Actor + 17, // 99: substrate.ateapi.v1.UpdateActorRequest.actor:type_name -> substrate.ateapi.v1.Actor + 35, // 100: substrate.ateapi.v1.SuspendActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 81, // 101: substrate.ateapi.v1.SuspendActorRequest.options:type_name -> substrate.ateapi.v1.SuspendOptions + 17, // 102: substrate.ateapi.v1.SuspendActorResponse.actor:type_name -> substrate.ateapi.v1.Actor + 7, // 103: substrate.ateapi.v1.SuspendOptions.mode:type_name -> substrate.ateapi.v1.DurabilityMode + 35, // 104: substrate.ateapi.v1.ResumeActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 17, // 105: substrate.ateapi.v1.ResumeActorResponse.actor:type_name -> substrate.ateapi.v1.Actor + 35, // 106: substrate.ateapi.v1.RevertActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 17, // 107: substrate.ateapi.v1.RevertActorResponse.actor:type_name -> substrate.ateapi.v1.Actor + 35, // 108: substrate.ateapi.v1.DeleteActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 99, // 109: substrate.ateapi.v1.DeleteActorRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 35, // 110: substrate.ateapi.v1.GetActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 111: substrate.ateapi.v1.CreateActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 18, // 112: substrate.ateapi.v1.CreateActorEgressPolicyRequest.egress_policy:type_name -> substrate.ateapi.v1.EgressPolicy + 35, // 113: substrate.ateapi.v1.UpdateActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 18, // 114: substrate.ateapi.v1.UpdateActorEgressPolicyRequest.egress_policy:type_name -> substrate.ateapi.v1.EgressPolicy + 35, // 115: substrate.ateapi.v1.DeleteActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 99, // 116: substrate.ateapi.v1.DeleteActorEgressPolicyRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 35, // 117: substrate.ateapi.v1.GetTagRequest.tag:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 118: substrate.ateapi.v1.MintActorJwtRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 160, // 119: substrate.ateapi.v1.MintActorJwtResponse.expire_time:type_name -> google.protobuf.Timestamp + 100, // 120: substrate.ateapi.v1.ListTagsRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 33, // 121: substrate.ateapi.v1.ListTagsResponse.tags:type_name -> substrate.ateapi.v1.Tag + 33, // 122: substrate.ateapi.v1.CreateTagRequest.tag:type_name -> substrate.ateapi.v1.Tag + 33, // 123: substrate.ateapi.v1.UpdateTagRequest.tag:type_name -> substrate.ateapi.v1.Tag + 35, // 124: substrate.ateapi.v1.DeleteTagRequest.tag:type_name -> substrate.ateapi.v1.ObjectRef + 99, // 125: substrate.ateapi.v1.DeleteTagRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 35, // 126: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 100, // 127: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 126, // 128: substrate.ateapi.v1.ListWorkerActorAssignmentsResponse.actor_assignments:type_name -> substrate.ateapi.v1.ActorAssignment + 100, // 129: substrate.ateapi.v1.ListWorkersRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 117, // 130: substrate.ateapi.v1.ListWorkersResponse.workers:type_name -> substrate.ateapi.v1.Worker + 35, // 131: substrate.ateapi.v1.GetWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 117, // 132: substrate.ateapi.v1.CreateWorkerRequest.worker:type_name -> substrate.ateapi.v1.Worker + 117, // 133: substrate.ateapi.v1.UpdateWorkerRequest.worker:type_name -> substrate.ateapi.v1.Worker + 35, // 134: substrate.ateapi.v1.DeleteWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 99, // 135: substrate.ateapi.v1.DeleteWorkerRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 35, // 136: substrate.ateapi.v1.DrainWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 117, // 137: substrate.ateapi.v1.DrainWorkerResponse.worker:type_name -> substrate.ateapi.v1.Worker + 35, // 138: substrate.ateapi.v1.MarkWorkerAvailableRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 117, // 139: substrate.ateapi.v1.MarkWorkerAvailableResponse.worker:type_name -> substrate.ateapi.v1.Worker + 35, // 140: substrate.ateapi.v1.MarkWorkerUnavailableRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 117, // 141: substrate.ateapi.v1.MarkWorkerUnavailableResponse.worker:type_name -> substrate.ateapi.v1.Worker + 100, // 142: substrate.ateapi.v1.ListActorsRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 17, // 143: substrate.ateapi.v1.ListActorsResponse.actors:type_name -> substrate.ateapi.v1.Actor + 14, // 144: substrate.ateapi.v1.Worker.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata + 159, // 145: substrate.ateapi.v1.Worker.labels:type_name -> substrate.ateapi.v1.Worker.LabelsEntry + 118, // 146: substrate.ateapi.v1.Worker.status:type_name -> substrate.ateapi.v1.WorkerStatus + 8, // 147: substrate.ateapi.v1.WorkerStatus.state:type_name -> substrate.ateapi.v1.WorkerState + 125, // 148: substrate.ateapi.v1.WorkerStatus.capacity:type_name -> substrate.ateapi.v1.WorkerResources + 125, // 149: substrate.ateapi.v1.WorkerStatus.allocated:type_name -> substrate.ateapi.v1.WorkerResources + 119, // 150: substrate.ateapi.v1.WorkerStatus.sandbox_classes:type_name -> substrate.ateapi.v1.WorkerSandboxClass + 120, // 151: substrate.ateapi.v1.WorkerSandboxClass.default_runtime:type_name -> substrate.ateapi.v1.WorkerSandboxRuntime + 120, // 152: substrate.ateapi.v1.WorkerSandboxClass.restorable_runtimes:type_name -> substrate.ateapi.v1.WorkerSandboxRuntime + 123, // 153: substrate.ateapi.v1.WorkerSandboxRuntime.version:type_name -> substrate.ateapi.v1.VersionedSandboxCompat + 121, // 154: substrate.ateapi.v1.WorkerSandboxRuntime.actor_overhead:type_name -> substrate.ateapi.v1.RuntimeOverhead + 123, // 155: substrate.ateapi.v1.ActorSandboxRuntime.version:type_name -> substrate.ateapi.v1.VersionedSandboxCompat + 124, // 156: substrate.ateapi.v1.VersionedSandboxCompat.attributes:type_name -> substrate.ateapi.v1.AttributeEntry + 14, // 157: substrate.ateapi.v1.ActorAssignment.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata + 35, // 158: substrate.ateapi.v1.ActorAssignment.actor:type_name -> substrate.ateapi.v1.ObjectRef + 38, // 159: substrate.ateapi.v1.ActorAssignment.resources:type_name -> substrate.ateapi.v1.Resources + 35, // 160: substrate.ateapi.v1.AcquireWorkerEpochRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 161: substrate.ateapi.v1.RegisterWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 125, // 162: substrate.ateapi.v1.RegisterWorkerRequest.capacity:type_name -> substrate.ateapi.v1.WorkerResources + 117, // 163: substrate.ateapi.v1.RegisterWorkerResponse.worker:type_name -> substrate.ateapi.v1.Worker + 35, // 164: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 119, // 165: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest.sandbox_classes:type_name -> substrate.ateapi.v1.WorkerSandboxClass + 117, // 166: substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse.worker:type_name -> substrate.ateapi.v1.Worker + 35, // 167: substrate.ateapi.v1.MintWorkerActorCertificateRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 168: substrate.ateapi.v1.MintWorkerActorCertificateRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 169: substrate.ateapi.v1.MintWorkerActorJwtRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 160, // 170: substrate.ateapi.v1.MintWorkerActorJwtResponse.expire_time:type_name -> google.protobuf.Timestamp + 35, // 171: substrate.ateapi.v1.RequestActorSuspendRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 172: substrate.ateapi.v1.RequestActorSuspendRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 17, // 173: substrate.ateapi.v1.RequestActorSuspendResponse.actor:type_name -> substrate.ateapi.v1.Actor + 35, // 174: substrate.ateapi.v1.ReportActorCrashedRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 175: substrate.ateapi.v1.ReportActorCrashedRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 17, // 176: substrate.ateapi.v1.ReportActorCrashedResponse.actor:type_name -> substrate.ateapi.v1.Actor + 35, // 177: substrate.ateapi.v1.ReportActorSnapshotStateRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 143, // 178: substrate.ateapi.v1.ReportActorSnapshotStateRequest.state:type_name -> substrate.ateapi.v1.ActorSnapshotState + 144, // 179: substrate.ateapi.v1.ActorSnapshotState.latest_local:type_name -> substrate.ateapi.v1.SnapshotReport + 144, // 180: substrate.ateapi.v1.ActorSnapshotState.uploading:type_name -> substrate.ateapi.v1.SnapshotReport + 144, // 181: substrate.ateapi.v1.ActorSnapshotState.latest_durable:type_name -> substrate.ateapi.v1.SnapshotReport + 160, // 182: substrate.ateapi.v1.ActorSnapshotState.upload_due_time:type_name -> google.protobuf.Timestamp + 2, // 183: substrate.ateapi.v1.SnapshotReport.fidelity:type_name -> substrate.ateapi.v1.SnapshotFidelity + 10, // 184: substrate.ateapi.v1.SnapshotReport.object:type_name -> substrate.ateapi.v1.ObjectSnapshot + 160, // 185: substrate.ateapi.v1.SnapshotReport.local_commit_time:type_name -> google.protobuf.Timestamp + 160, // 186: substrate.ateapi.v1.SnapshotReport.durable_complete_time:type_name -> google.protobuf.Timestamp + 14, // 187: substrate.ateapi.v1.AccessPolicy.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata + 146, // 188: substrate.ateapi.v1.AccessPolicy.bindings:type_name -> substrate.ateapi.v1.Binding + 145, // 189: substrate.ateapi.v1.CreateGlobalAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy + 145, // 190: substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy + 35, // 191: substrate.ateapi.v1.GetAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 192: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef + 145, // 193: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy + 35, // 194: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef + 145, // 195: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy + 35, // 196: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef + 99, // 197: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 9, // 198: substrate.ateapi.v1.ResourceAnnotation.scope:type_name -> substrate.ateapi.v1.Scope + 161, // 199: substrate.ateapi.v1.resource:extendee -> google.protobuf.MessageOptions + 162, // 200: substrate.ateapi.v1.method:extendee -> google.protobuf.MethodOptions + 154, // 201: substrate.ateapi.v1.resource:type_name -> substrate.ateapi.v1.ResourceAnnotation + 155, // 202: substrate.ateapi.v1.method:type_name -> substrate.ateapi.v1.MethodAnnotation + 76, // 203: substrate.ateapi.v1.Control.GetActor:input_type -> substrate.ateapi.v1.GetActorRequest + 77, // 204: substrate.ateapi.v1.Control.CreateActor:input_type -> substrate.ateapi.v1.CreateActorRequest + 78, // 205: substrate.ateapi.v1.Control.UpdateActor:input_type -> substrate.ateapi.v1.UpdateActorRequest + 79, // 206: substrate.ateapi.v1.Control.SuspendActor:input_type -> substrate.ateapi.v1.SuspendActorRequest + 82, // 207: substrate.ateapi.v1.Control.ResumeActor:input_type -> substrate.ateapi.v1.ResumeActorRequest + 84, // 208: substrate.ateapi.v1.Control.RevertActor:input_type -> substrate.ateapi.v1.RevertActorRequest + 86, // 209: substrate.ateapi.v1.Control.DeleteActor:input_type -> substrate.ateapi.v1.DeleteActorRequest + 87, // 210: substrate.ateapi.v1.Control.GetActorEgressPolicy:input_type -> substrate.ateapi.v1.GetActorEgressPolicyRequest + 88, // 211: substrate.ateapi.v1.Control.CreateActorEgressPolicy:input_type -> substrate.ateapi.v1.CreateActorEgressPolicyRequest + 89, // 212: substrate.ateapi.v1.Control.UpdateActorEgressPolicy:input_type -> substrate.ateapi.v1.UpdateActorEgressPolicyRequest + 90, // 213: substrate.ateapi.v1.Control.DeleteActorEgressPolicy:input_type -> substrate.ateapi.v1.DeleteActorEgressPolicyRequest + 92, // 214: substrate.ateapi.v1.Control.MintActorJwt:input_type -> substrate.ateapi.v1.MintActorJwtRequest + 96, // 215: substrate.ateapi.v1.Control.CreateTag:input_type -> substrate.ateapi.v1.CreateTagRequest + 91, // 216: substrate.ateapi.v1.Control.GetTag:input_type -> substrate.ateapi.v1.GetTagRequest + 94, // 217: substrate.ateapi.v1.Control.ListTags:input_type -> substrate.ateapi.v1.ListTagsRequest + 97, // 218: substrate.ateapi.v1.Control.UpdateTag:input_type -> substrate.ateapi.v1.UpdateTagRequest + 98, // 219: substrate.ateapi.v1.Control.DeleteTag:input_type -> substrate.ateapi.v1.DeleteTagRequest + 103, // 220: substrate.ateapi.v1.Control.ListWorkers:input_type -> substrate.ateapi.v1.ListWorkersRequest + 105, // 221: substrate.ateapi.v1.Control.GetWorker:input_type -> substrate.ateapi.v1.GetWorkerRequest + 106, // 222: substrate.ateapi.v1.Control.CreateWorker:input_type -> substrate.ateapi.v1.CreateWorkerRequest + 107, // 223: substrate.ateapi.v1.Control.UpdateWorker:input_type -> substrate.ateapi.v1.UpdateWorkerRequest + 108, // 224: substrate.ateapi.v1.Control.DeleteWorker:input_type -> substrate.ateapi.v1.DeleteWorkerRequest + 109, // 225: substrate.ateapi.v1.Control.DrainWorker:input_type -> substrate.ateapi.v1.DrainWorkerRequest + 111, // 226: substrate.ateapi.v1.Control.MarkWorkerAvailable:input_type -> substrate.ateapi.v1.MarkWorkerAvailableRequest + 113, // 227: substrate.ateapi.v1.Control.MarkWorkerUnavailable:input_type -> substrate.ateapi.v1.MarkWorkerUnavailableRequest + 101, // 228: substrate.ateapi.v1.Control.ListWorkerActorAssignments:input_type -> substrate.ateapi.v1.ListWorkerActorAssignmentsRequest + 115, // 229: substrate.ateapi.v1.Control.ListActors:input_type -> substrate.ateapi.v1.ListActorsRequest + 61, // 230: substrate.ateapi.v1.Control.CreateAtespace:input_type -> substrate.ateapi.v1.CreateAtespaceRequest + 62, // 231: substrate.ateapi.v1.Control.GetAtespace:input_type -> substrate.ateapi.v1.GetAtespaceRequest + 63, // 232: substrate.ateapi.v1.Control.ListAtespaces:input_type -> substrate.ateapi.v1.ListAtespacesRequest + 65, // 233: substrate.ateapi.v1.Control.DeleteAtespace:input_type -> substrate.ateapi.v1.DeleteAtespaceRequest + 66, // 234: substrate.ateapi.v1.Control.CreateExternalVolumeClass:input_type -> substrate.ateapi.v1.CreateExternalVolumeClassRequest + 67, // 235: substrate.ateapi.v1.Control.GetExternalVolumeClass:input_type -> substrate.ateapi.v1.GetExternalVolumeClassRequest + 68, // 236: substrate.ateapi.v1.Control.ListExternalVolumeClasses:input_type -> substrate.ateapi.v1.ListExternalVolumeClassesRequest + 70, // 237: substrate.ateapi.v1.Control.DeleteExternalVolumeClass:input_type -> substrate.ateapi.v1.DeleteExternalVolumeClassRequest + 71, // 238: substrate.ateapi.v1.Control.CreateActorTemplate:input_type -> substrate.ateapi.v1.CreateActorTemplateRequest + 72, // 239: substrate.ateapi.v1.Control.GetActorTemplate:input_type -> substrate.ateapi.v1.GetActorTemplateRequest + 73, // 240: substrate.ateapi.v1.Control.ListActorTemplates:input_type -> substrate.ateapi.v1.ListActorTemplatesRequest + 75, // 241: substrate.ateapi.v1.Control.DeleteActorTemplate:input_type -> substrate.ateapi.v1.DeleteActorTemplateRequest + 147, // 242: substrate.ateapi.v1.Control.GetGlobalAccessPolicy:input_type -> substrate.ateapi.v1.GetGlobalAccessPolicyRequest + 148, // 243: substrate.ateapi.v1.Control.CreateGlobalAccessPolicy:input_type -> substrate.ateapi.v1.CreateGlobalAccessPolicyRequest + 149, // 244: substrate.ateapi.v1.Control.UpdateGlobalAccessPolicy:input_type -> substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest + 150, // 245: substrate.ateapi.v1.Control.GetAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.GetAtespaceAccessPolicyRequest + 151, // 246: substrate.ateapi.v1.Control.CreateAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest + 152, // 247: substrate.ateapi.v1.Control.UpdateAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest + 153, // 248: substrate.ateapi.v1.Control.DeleteAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest + 127, // 249: substrate.ateapi.v1.WorkerService.AcquireWorkerEpoch:input_type -> substrate.ateapi.v1.AcquireWorkerEpochRequest + 129, // 250: substrate.ateapi.v1.WorkerService.RegisterWorker:input_type -> substrate.ateapi.v1.RegisterWorkerRequest + 131, // 251: substrate.ateapi.v1.WorkerService.SetWorkerSandboxRuntimes:input_type -> substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest + 133, // 252: substrate.ateapi.v1.WorkerService.MintWorkerActorCertificate:input_type -> substrate.ateapi.v1.MintWorkerActorCertificateRequest + 135, // 253: substrate.ateapi.v1.WorkerService.MintWorkerActorJwt:input_type -> substrate.ateapi.v1.MintWorkerActorJwtRequest + 137, // 254: substrate.ateapi.v1.WorkerService.RequestActorSuspend:input_type -> substrate.ateapi.v1.RequestActorSuspendRequest + 141, // 255: substrate.ateapi.v1.WorkerService.ReportActorSnapshotState:input_type -> substrate.ateapi.v1.ReportActorSnapshotStateRequest + 139, // 256: substrate.ateapi.v1.WorkerService.ReportActorCrashed:input_type -> substrate.ateapi.v1.ReportActorCrashedRequest + 17, // 257: substrate.ateapi.v1.Control.GetActor:output_type -> substrate.ateapi.v1.Actor + 17, // 258: substrate.ateapi.v1.Control.CreateActor:output_type -> substrate.ateapi.v1.Actor + 17, // 259: substrate.ateapi.v1.Control.UpdateActor:output_type -> substrate.ateapi.v1.Actor + 80, // 260: substrate.ateapi.v1.Control.SuspendActor:output_type -> substrate.ateapi.v1.SuspendActorResponse + 83, // 261: substrate.ateapi.v1.Control.ResumeActor:output_type -> substrate.ateapi.v1.ResumeActorResponse + 85, // 262: substrate.ateapi.v1.Control.RevertActor:output_type -> substrate.ateapi.v1.RevertActorResponse + 17, // 263: substrate.ateapi.v1.Control.DeleteActor:output_type -> substrate.ateapi.v1.Actor + 18, // 264: substrate.ateapi.v1.Control.GetActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy + 18, // 265: substrate.ateapi.v1.Control.CreateActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy + 18, // 266: substrate.ateapi.v1.Control.UpdateActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy + 18, // 267: substrate.ateapi.v1.Control.DeleteActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy + 93, // 268: substrate.ateapi.v1.Control.MintActorJwt:output_type -> substrate.ateapi.v1.MintActorJwtResponse + 33, // 269: substrate.ateapi.v1.Control.CreateTag:output_type -> substrate.ateapi.v1.Tag + 33, // 270: substrate.ateapi.v1.Control.GetTag:output_type -> substrate.ateapi.v1.Tag + 95, // 271: substrate.ateapi.v1.Control.ListTags:output_type -> substrate.ateapi.v1.ListTagsResponse + 33, // 272: substrate.ateapi.v1.Control.UpdateTag:output_type -> substrate.ateapi.v1.Tag + 33, // 273: substrate.ateapi.v1.Control.DeleteTag:output_type -> substrate.ateapi.v1.Tag + 104, // 274: substrate.ateapi.v1.Control.ListWorkers:output_type -> substrate.ateapi.v1.ListWorkersResponse + 117, // 275: substrate.ateapi.v1.Control.GetWorker:output_type -> substrate.ateapi.v1.Worker + 117, // 276: substrate.ateapi.v1.Control.CreateWorker:output_type -> substrate.ateapi.v1.Worker + 117, // 277: substrate.ateapi.v1.Control.UpdateWorker:output_type -> substrate.ateapi.v1.Worker + 117, // 278: substrate.ateapi.v1.Control.DeleteWorker:output_type -> substrate.ateapi.v1.Worker + 110, // 279: substrate.ateapi.v1.Control.DrainWorker:output_type -> substrate.ateapi.v1.DrainWorkerResponse + 112, // 280: substrate.ateapi.v1.Control.MarkWorkerAvailable:output_type -> substrate.ateapi.v1.MarkWorkerAvailableResponse + 114, // 281: substrate.ateapi.v1.Control.MarkWorkerUnavailable:output_type -> substrate.ateapi.v1.MarkWorkerUnavailableResponse + 102, // 282: substrate.ateapi.v1.Control.ListWorkerActorAssignments:output_type -> substrate.ateapi.v1.ListWorkerActorAssignmentsResponse + 116, // 283: substrate.ateapi.v1.Control.ListActors:output_type -> substrate.ateapi.v1.ListActorsResponse + 34, // 284: substrate.ateapi.v1.Control.CreateAtespace:output_type -> substrate.ateapi.v1.Atespace + 34, // 285: substrate.ateapi.v1.Control.GetAtespace:output_type -> substrate.ateapi.v1.Atespace + 64, // 286: substrate.ateapi.v1.Control.ListAtespaces:output_type -> substrate.ateapi.v1.ListAtespacesResponse + 34, // 287: substrate.ateapi.v1.Control.DeleteAtespace:output_type -> substrate.ateapi.v1.Atespace + 54, // 288: substrate.ateapi.v1.Control.CreateExternalVolumeClass:output_type -> substrate.ateapi.v1.ExternalVolumeClass + 54, // 289: substrate.ateapi.v1.Control.GetExternalVolumeClass:output_type -> substrate.ateapi.v1.ExternalVolumeClass + 69, // 290: substrate.ateapi.v1.Control.ListExternalVolumeClasses:output_type -> substrate.ateapi.v1.ListExternalVolumeClassesResponse + 54, // 291: substrate.ateapi.v1.Control.DeleteExternalVolumeClass:output_type -> substrate.ateapi.v1.ExternalVolumeClass + 36, // 292: substrate.ateapi.v1.Control.CreateActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate + 36, // 293: substrate.ateapi.v1.Control.GetActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate + 74, // 294: substrate.ateapi.v1.Control.ListActorTemplates:output_type -> substrate.ateapi.v1.ListActorTemplatesResponse + 36, // 295: substrate.ateapi.v1.Control.DeleteActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate + 145, // 296: substrate.ateapi.v1.Control.GetGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 145, // 297: substrate.ateapi.v1.Control.CreateGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 145, // 298: substrate.ateapi.v1.Control.UpdateGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 145, // 299: substrate.ateapi.v1.Control.GetAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 145, // 300: substrate.ateapi.v1.Control.CreateAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 145, // 301: substrate.ateapi.v1.Control.UpdateAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 145, // 302: substrate.ateapi.v1.Control.DeleteAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 128, // 303: substrate.ateapi.v1.WorkerService.AcquireWorkerEpoch:output_type -> substrate.ateapi.v1.AcquireWorkerEpochResponse + 130, // 304: substrate.ateapi.v1.WorkerService.RegisterWorker:output_type -> substrate.ateapi.v1.RegisterWorkerResponse + 132, // 305: substrate.ateapi.v1.WorkerService.SetWorkerSandboxRuntimes:output_type -> substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse + 134, // 306: substrate.ateapi.v1.WorkerService.MintWorkerActorCertificate:output_type -> substrate.ateapi.v1.MintWorkerActorCertificateResponse + 136, // 307: substrate.ateapi.v1.WorkerService.MintWorkerActorJwt:output_type -> substrate.ateapi.v1.MintWorkerActorJwtResponse + 138, // 308: substrate.ateapi.v1.WorkerService.RequestActorSuspend:output_type -> substrate.ateapi.v1.RequestActorSuspendResponse + 142, // 309: substrate.ateapi.v1.WorkerService.ReportActorSnapshotState:output_type -> substrate.ateapi.v1.ReportActorSnapshotStateResponse + 140, // 310: substrate.ateapi.v1.WorkerService.ReportActorCrashed:output_type -> substrate.ateapi.v1.ReportActorCrashedResponse + 257, // [257:311] is the sub-list for method output_type + 203, // [203:257] is the sub-list for method input_type + 201, // [201:203] is the sub-list for extension type_name + 199, // [199:201] is the sub-list for extension extendee + 0, // [0:199] is the sub-list for field type_name } func init() { file_api_ateapi_v1_ateapi_proto_init() } @@ -11231,7 +11533,7 @@ func file_api_ateapi_v1_ateapi_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_api_ateapi_v1_ateapi_proto_rawDesc), len(file_api_ateapi_v1_ateapi_proto_rawDesc)), NumEnums: 10, - NumMessages: 145, + NumMessages: 150, NumExtensions: 2, NumServices: 2, }, diff --git a/api/ateapi/v1/ateapi.proto b/api/ateapi/v1/ateapi.proto index 0f1f457a5e..89977164d2 100644 --- a/api/ateapi/v1/ateapi.proto +++ b/api/ateapi/v1/ateapi.proto @@ -203,6 +203,28 @@ service Control { option (method).resource = "Atespace"; } + // Create an ExternalVolumeClass. + rpc CreateExternalVolumeClass(CreateExternalVolumeClassRequest) returns (ExternalVolumeClass) { + option (method).resource = "ExternalVolumeClass"; + } + + // Get an ExternalVolumeClass by name. + rpc GetExternalVolumeClass(GetExternalVolumeClassRequest) returns (ExternalVolumeClass) { + option (method).resource = "ExternalVolumeClass"; + } + + // List ExternalVolumeClasses. + rpc ListExternalVolumeClasses(ListExternalVolumeClassesRequest) returns (ListExternalVolumeClassesResponse) { + option (method).resource = "ExternalVolumeClass"; + } + + // Delete an ExternalVolumeClass. Delete does not check for ActorTemplates + // that still reference the class. Volumes from those templates then fail to + // provision. + rpc DeleteExternalVolumeClass(DeleteExternalVolumeClassRequest) returns (ExternalVolumeClass) { + option (method).resource = "ExternalVolumeClass"; + } + rpc CreateActorTemplate(CreateActorTemplateRequest) returns (ActorTemplate) { option (method).resource = "ActorTemplate"; } @@ -1753,6 +1775,57 @@ message DeleteAtespaceRequest { DeleteOptions options = 2; } +// CreateExternalVolumeClassRequest creates an ExternalVolumeClass. +message CreateExternalVolumeClassRequest { + // The class to create. metadata.name is required and metadata.atespace + // must be empty. + // + // +ate:preview=ExternalVolumes + // +k8s:ifDisabled(ExternalVolumes)=+k8s:forbidden + // +k8s:required + ExternalVolumeClass external_volume_class = 1; +} + +// GetExternalVolumeClassRequest identifies the ExternalVolumeClass to get. +message GetExternalVolumeClassRequest { + // The class to get. atespace must be empty. + // + // +k8s:required + // +k8s:beta(since: "0.0")=+k8s:subfield(atespace)=+k8s:forbidden # TODO: get rid of beta prefix + ObjectRef external_volume_class = 1; +} + +// ListExternalVolumeClassesRequest asks for a page of ExternalVolumeClasses. +message ListExternalVolumeClassesRequest { + // Pagination controls. + // + // +k8s:optional + ListOptions options = 1; +} + +// ListExternalVolumeClassesResponse is one page of ExternalVolumeClasses. +message ListExternalVolumeClassesResponse { + // The page of classes. This list may be empty even if there are more results. + repeated ExternalVolumeClass external_volume_classes = 1; + + // Pagination token for the next page. Empty if this is the last page. + string next_page_token = 2; +} + +// DeleteExternalVolumeClassRequest identifies the ExternalVolumeClass to delete. +message DeleteExternalVolumeClassRequest { + // The class to delete. atespace must be empty. + // + // +k8s:required + // +k8s:beta(since: "0.0")=+k8s:subfield(atespace)=+k8s:forbidden # TODO: get rid of beta prefix + ObjectRef external_volume_class = 1; + + // Optional per-delete preconditions. + // + // +k8s:optional + DeleteOptions options = 2; +} + message CreateActorTemplateRequest { // The actor template version to create. Server-assigned metadata (uid, // version, timestamps) is ignored, as are the status fields. diff --git a/api/ateapi/v1/ateapi_grpc.pb.go b/api/ateapi/v1/ateapi_grpc.pb.go index e54c306d67..1432abcebf 100644 --- a/api/ateapi/v1/ateapi_grpc.pb.go +++ b/api/ateapi/v1/ateapi_grpc.pb.go @@ -64,6 +64,10 @@ const ( Control_GetAtespace_FullMethodName = "/substrate.ateapi.v1.Control/GetAtespace" Control_ListAtespaces_FullMethodName = "/substrate.ateapi.v1.Control/ListAtespaces" Control_DeleteAtespace_FullMethodName = "/substrate.ateapi.v1.Control/DeleteAtespace" + Control_CreateExternalVolumeClass_FullMethodName = "/substrate.ateapi.v1.Control/CreateExternalVolumeClass" + Control_GetExternalVolumeClass_FullMethodName = "/substrate.ateapi.v1.Control/GetExternalVolumeClass" + Control_ListExternalVolumeClasses_FullMethodName = "/substrate.ateapi.v1.Control/ListExternalVolumeClasses" + Control_DeleteExternalVolumeClass_FullMethodName = "/substrate.ateapi.v1.Control/DeleteExternalVolumeClass" Control_CreateActorTemplate_FullMethodName = "/substrate.ateapi.v1.Control/CreateActorTemplate" Control_GetActorTemplate_FullMethodName = "/substrate.ateapi.v1.Control/GetActorTemplate" Control_ListActorTemplates_FullMethodName = "/substrate.ateapi.v1.Control/ListActorTemplates" @@ -170,6 +174,16 @@ type ControlClient interface { // Delete an empty Atespace. Rejects (FailedPrecondition) if any Actors or // Tags remain. DeleteAtespace(ctx context.Context, in *DeleteAtespaceRequest, opts ...grpc.CallOption) (*Atespace, error) + // Create an ExternalVolumeClass. + CreateExternalVolumeClass(ctx context.Context, in *CreateExternalVolumeClassRequest, opts ...grpc.CallOption) (*ExternalVolumeClass, error) + // Get an ExternalVolumeClass by name. + GetExternalVolumeClass(ctx context.Context, in *GetExternalVolumeClassRequest, opts ...grpc.CallOption) (*ExternalVolumeClass, error) + // List ExternalVolumeClasses. + ListExternalVolumeClasses(ctx context.Context, in *ListExternalVolumeClassesRequest, opts ...grpc.CallOption) (*ListExternalVolumeClassesResponse, error) + // Delete an ExternalVolumeClass. Delete does not check for ActorTemplates + // that still reference the class. Volumes from those templates then fail to + // provision. + DeleteExternalVolumeClass(ctx context.Context, in *DeleteExternalVolumeClassRequest, opts ...grpc.CallOption) (*ExternalVolumeClass, error) CreateActorTemplate(ctx context.Context, in *CreateActorTemplateRequest, opts ...grpc.CallOption) (*ActorTemplate, error) GetActorTemplate(ctx context.Context, in *GetActorTemplateRequest, opts ...grpc.CallOption) (*ActorTemplate, error) ListActorTemplates(ctx context.Context, in *ListActorTemplatesRequest, opts ...grpc.CallOption) (*ListActorTemplatesResponse, error) @@ -515,6 +529,46 @@ func (c *controlClient) DeleteAtespace(ctx context.Context, in *DeleteAtespaceRe return out, nil } +func (c *controlClient) CreateExternalVolumeClass(ctx context.Context, in *CreateExternalVolumeClassRequest, opts ...grpc.CallOption) (*ExternalVolumeClass, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ExternalVolumeClass) + err := c.cc.Invoke(ctx, Control_CreateExternalVolumeClass_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *controlClient) GetExternalVolumeClass(ctx context.Context, in *GetExternalVolumeClassRequest, opts ...grpc.CallOption) (*ExternalVolumeClass, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ExternalVolumeClass) + err := c.cc.Invoke(ctx, Control_GetExternalVolumeClass_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *controlClient) ListExternalVolumeClasses(ctx context.Context, in *ListExternalVolumeClassesRequest, opts ...grpc.CallOption) (*ListExternalVolumeClassesResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListExternalVolumeClassesResponse) + err := c.cc.Invoke(ctx, Control_ListExternalVolumeClasses_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *controlClient) DeleteExternalVolumeClass(ctx context.Context, in *DeleteExternalVolumeClassRequest, opts ...grpc.CallOption) (*ExternalVolumeClass, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ExternalVolumeClass) + err := c.cc.Invoke(ctx, Control_DeleteExternalVolumeClass_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *controlClient) CreateActorTemplate(ctx context.Context, in *CreateActorTemplateRequest, opts ...grpc.CallOption) (*ActorTemplate, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(ActorTemplate) @@ -718,6 +772,16 @@ type ControlServer interface { // Delete an empty Atespace. Rejects (FailedPrecondition) if any Actors or // Tags remain. DeleteAtespace(context.Context, *DeleteAtespaceRequest) (*Atespace, error) + // Create an ExternalVolumeClass. + CreateExternalVolumeClass(context.Context, *CreateExternalVolumeClassRequest) (*ExternalVolumeClass, error) + // Get an ExternalVolumeClass by name. + GetExternalVolumeClass(context.Context, *GetExternalVolumeClassRequest) (*ExternalVolumeClass, error) + // List ExternalVolumeClasses. + ListExternalVolumeClasses(context.Context, *ListExternalVolumeClassesRequest) (*ListExternalVolumeClassesResponse, error) + // Delete an ExternalVolumeClass. Delete does not check for ActorTemplates + // that still reference the class. Volumes from those templates then fail to + // provision. + DeleteExternalVolumeClass(context.Context, *DeleteExternalVolumeClassRequest) (*ExternalVolumeClass, error) CreateActorTemplate(context.Context, *CreateActorTemplateRequest) (*ActorTemplate, error) GetActorTemplate(context.Context, *GetActorTemplateRequest) (*ActorTemplate, error) ListActorTemplates(context.Context, *ListActorTemplatesRequest) (*ListActorTemplatesResponse, error) @@ -846,6 +910,18 @@ func (UnimplementedControlServer) ListAtespaces(context.Context, *ListAtespacesR func (UnimplementedControlServer) DeleteAtespace(context.Context, *DeleteAtespaceRequest) (*Atespace, error) { return nil, status.Error(codes.Unimplemented, "method DeleteAtespace not implemented") } +func (UnimplementedControlServer) CreateExternalVolumeClass(context.Context, *CreateExternalVolumeClassRequest) (*ExternalVolumeClass, error) { + return nil, status.Error(codes.Unimplemented, "method CreateExternalVolumeClass not implemented") +} +func (UnimplementedControlServer) GetExternalVolumeClass(context.Context, *GetExternalVolumeClassRequest) (*ExternalVolumeClass, error) { + return nil, status.Error(codes.Unimplemented, "method GetExternalVolumeClass not implemented") +} +func (UnimplementedControlServer) ListExternalVolumeClasses(context.Context, *ListExternalVolumeClassesRequest) (*ListExternalVolumeClassesResponse, error) { + return nil, status.Error(codes.Unimplemented, "method ListExternalVolumeClasses not implemented") +} +func (UnimplementedControlServer) DeleteExternalVolumeClass(context.Context, *DeleteExternalVolumeClassRequest) (*ExternalVolumeClass, error) { + return nil, status.Error(codes.Unimplemented, "method DeleteExternalVolumeClass not implemented") +} func (UnimplementedControlServer) CreateActorTemplate(context.Context, *CreateActorTemplateRequest) (*ActorTemplate, error) { return nil, status.Error(codes.Unimplemented, "method CreateActorTemplate not implemented") } @@ -1458,6 +1534,78 @@ func _Control_DeleteAtespace_Handler(srv interface{}, ctx context.Context, dec f return interceptor(ctx, in, info, handler) } +func _Control_CreateExternalVolumeClass_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateExternalVolumeClassRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ControlServer).CreateExternalVolumeClass(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Control_CreateExternalVolumeClass_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ControlServer).CreateExternalVolumeClass(ctx, req.(*CreateExternalVolumeClassRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Control_GetExternalVolumeClass_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetExternalVolumeClassRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ControlServer).GetExternalVolumeClass(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Control_GetExternalVolumeClass_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ControlServer).GetExternalVolumeClass(ctx, req.(*GetExternalVolumeClassRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Control_ListExternalVolumeClasses_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListExternalVolumeClassesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ControlServer).ListExternalVolumeClasses(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Control_ListExternalVolumeClasses_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ControlServer).ListExternalVolumeClasses(ctx, req.(*ListExternalVolumeClassesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Control_DeleteExternalVolumeClass_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteExternalVolumeClassRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ControlServer).DeleteExternalVolumeClass(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Control_DeleteExternalVolumeClass_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ControlServer).DeleteExternalVolumeClass(ctx, req.(*DeleteExternalVolumeClassRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Control_CreateActorTemplate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(CreateActorTemplateRequest) if err := dec(in); err != nil { @@ -1787,6 +1935,22 @@ var Control_ServiceDesc = grpc.ServiceDesc{ MethodName: "DeleteAtespace", Handler: _Control_DeleteAtespace_Handler, }, + { + MethodName: "CreateExternalVolumeClass", + Handler: _Control_CreateExternalVolumeClass_Handler, + }, + { + MethodName: "GetExternalVolumeClass", + Handler: _Control_GetExternalVolumeClass_Handler, + }, + { + MethodName: "ListExternalVolumeClasses", + Handler: _Control_ListExternalVolumeClasses_Handler, + }, + { + MethodName: "DeleteExternalVolumeClass", + Handler: _Control_DeleteExternalVolumeClass_Handler, + }, { MethodName: "CreateActorTemplate", Handler: _Control_CreateActorTemplate_Handler, diff --git a/cmd/ateapi/internal/apivalidation/external_volume_class.go b/cmd/ateapi/internal/apivalidation/external_volume_class.go new file mode 100644 index 0000000000..43f6d8c562 --- /dev/null +++ b/cmd/ateapi/internal/apivalidation/external_volume_class.go @@ -0,0 +1,44 @@ +// Copyright 2026 The Agent Substrate Authors +// +// 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" + + "go.ate.dev/substrate/api/ateapi/v1" + "go.ate.dev/substrate/internal/resources" + "k8s.io/apimachinery/pkg/api/operation" + "k8s.io/apimachinery/pkg/util/validation/field" +) + +func ValidateCreateExternalVolumeClassRequest(ctx context.Context, req *ateapi.CreateExternalVolumeClassRequest) field.ErrorList { + return Validate_CreateExternalVolumeClassRequest(ctx, MakeCreateOp(ctx), nil, req, nil) +} + +func ValidateGetExternalVolumeClassRequest(ctx context.Context, req *ateapi.GetExternalVolumeClassRequest) field.ErrorList { + return Validate_GetExternalVolumeClassRequest(ctx, MakeCreateOp(ctx), nil, req, nil) +} + +func ValidateListExternalVolumeClassesRequest(ctx context.Context, req *ateapi.ListExternalVolumeClassesRequest) field.ErrorList { + return Validate_ListExternalVolumeClassesRequest(ctx, MakeCreateOp(ctx), nil, req, nil) +} + +func ValidateDeleteExternalVolumeClassRequest(ctx context.Context, req *ateapi.DeleteExternalVolumeClassRequest) field.ErrorList { + return Validate_DeleteExternalVolumeClassRequest(ctx, MakeCreateOp(ctx), nil, req, nil) +} + +func ValidateCustom_ExternalVolumeClass_DriverName(_ context.Context, _ operation.Operation, fldPath *field.Path, value, _ *string) field.ErrorList { + return resources.ValidateVolumeType(fldPath, *value) +} diff --git a/cmd/ateapi/internal/apivalidation/external_volume_class_test.go b/cmd/ateapi/internal/apivalidation/external_volume_class_test.go new file mode 100644 index 0000000000..9c023c015a --- /dev/null +++ b/cmd/ateapi/internal/apivalidation/external_volume_class_test.go @@ -0,0 +1,135 @@ +// Copyright 2026 The Agent Substrate Authors +// +// 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" + "strings" + "testing" + + "go.ate.dev/substrate/api/ateapi/v1" + "k8s.io/apimachinery/pkg/util/validation/field" +) + +func TestValidateCreateExternalVolumeClassRequest(t *testing.T) { + evc := field.NewPath("external_volume_class") + tests := []struct { + name string + mutate func(*ateapi.ExternalVolumeClass) + want field.ErrorList + wantWithPreview field.ErrorList + }{{ + name: "valid", + want: field.ErrorList{field.Forbidden(evc, "")}, + }, { + name: "driver_name with substrate.io/ prefix", + mutate: func(c *ateapi.ExternalVolumeClass) { c.DriverName = "substrate.io/mock" }, + want: field.ErrorList{field.Forbidden(evc, "")}, + wantWithPreview: nil, + }, { + name: "metadata.atespace must be empty", + mutate: func(c *ateapi.ExternalVolumeClass) { c.Metadata.Atespace = "as" }, + want: field.ErrorList{field.Forbidden(evc, "")}, + wantWithPreview: field.ErrorList{field.Forbidden(evc.Child("metadata", "atespace"), "")}, + }, { + name: "missing driver_name", + mutate: func(c *ateapi.ExternalVolumeClass) { c.DriverName = "" }, + want: field.ErrorList{field.Forbidden(evc, "")}, + wantWithPreview: field.ErrorList{field.Required(evc.Child("driver_name"), "")}, + }, { + name: "invalid driver_name", + mutate: func(c *ateapi.ExternalVolumeClass) { c.DriverName = "Bad_Driver" }, + want: field.ErrorList{field.Forbidden(evc, "")}, + wantWithPreview: field.ErrorList{field.Invalid(evc.Child("driver_name"), nil, "")}, + }, { + name: "too-long driver_name", + mutate: func(c *ateapi.ExternalVolumeClass) { c.DriverName = "nfs.csi." + strings.Repeat("a", 56) }, + want: field.ErrorList{field.Forbidden(evc, "")}, + wantWithPreview: field.ErrorList{field.TooLong(evc.Child("driver_name"), "", 63).WithOrigin("maxLength")}, + }, { + name: "too many parameters", + mutate: func(c *ateapi.ExternalVolumeClass) { c.Parameters = selectorLabelsOfSize(33) }, + want: field.ErrorList{field.Forbidden(evc, "")}, + wantWithPreview: field.ErrorList{field.TooMany(evc.Child("parameters"), 33, 32).WithOrigin("maxProperties")}, + }, { + name: "too-long parameter value", + mutate: func(c *ateapi.ExternalVolumeClass) { c.Parameters = map[string]string{"k": strings.Repeat("v", 257)} }, + want: field.ErrorList{field.Forbidden(evc, "")}, + wantWithPreview: field.ErrorList{field.TooLong(evc.Child("parameters").Key("k"), "", 256).WithOrigin("maxLength")}, + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &ateapi.ExternalVolumeClass{ + Metadata: &ateapi.ResourceMetadata{Name: "nfs"}, + DriverName: "nfs.csi.k8s.io", + } + if tt.mutate != nil { + tt.mutate(c) + } + req := &ateapi.CreateExternalVolumeClassRequest{ExternalVolumeClass: c} + assertValidate(t, func() field.ErrorList { return ValidateCreateExternalVolumeClassRequest(context.Background(), req) }, + tt.want, map[string]field.ErrorList{"ExternalVolumes": tt.wantWithPreview}) + }) + } + t.Run("missing external_volume_class", func(t *testing.T) { + assertValidateErr(t, ValidateCreateExternalVolumeClassRequest(context.Background(), &ateapi.CreateExternalVolumeClassRequest{}), + field.ErrorList{field.Required(evc, "")}) + }) +} + +var externalVolumeClassRefCases = []struct { + name string + ref *ateapi.ObjectRef + want field.ErrorList +}{ + {"valid", &ateapi.ObjectRef{Name: "nfs"}, nil}, + {"missing ref", nil, field.ErrorList{field.Required(field.NewPath("external_volume_class"), "")}}, + {"atespace must be empty", &ateapi.ObjectRef{Atespace: "as", Name: "nfs"}, field.ErrorList{field.Forbidden(field.NewPath("external_volume_class", "atespace"), "")}}, + {"missing name", &ateapi.ObjectRef{}, field.ErrorList{field.Required(field.NewPath("external_volume_class", "name"), "")}}, +} + +func TestValidateGetExternalVolumeClassRequest(t *testing.T) { + for _, tt := range externalVolumeClassRefCases { + t.Run(tt.name, func(t *testing.T) { + req := &ateapi.GetExternalVolumeClassRequest{ExternalVolumeClass: tt.ref} + assertValidateErr(t, ValidateGetExternalVolumeClassRequest(context.Background(), req), tt.want) + }) + } +} + +func TestValidateDeleteExternalVolumeClassRequest(t *testing.T) { + for _, tt := range externalVolumeClassRefCases { + t.Run(tt.name, func(t *testing.T) { + req := &ateapi.DeleteExternalVolumeClassRequest{ExternalVolumeClass: tt.ref} + assertValidateErr(t, ValidateDeleteExternalVolumeClassRequest(context.Background(), req), tt.want) + }) + } +} + +func TestValidateListExternalVolumeClassesRequest(t *testing.T) { + tests := []struct { + name string + req *ateapi.ListExternalVolumeClassesRequest + want field.ErrorList + }{ + {"valid", &ateapi.ListExternalVolumeClassesRequest{}, nil}, + {"negative page_size", &ateapi.ListExternalVolumeClassesRequest{Options: &ateapi.ListOptions{PageSize: -1}}, field.ErrorList{field.Invalid(field.NewPath("options", "page_size"), int32(-1), "").WithOrigin("minimum")}}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assertValidateErr(t, ValidateListExternalVolumeClassesRequest(context.Background(), tt.req), tt.want) + }) + } +} diff --git a/cmd/ateapi/internal/apivalidation/zz_generated.validation.go b/cmd/ateapi/internal/apivalidation/zz_generated.validation.go index 4719d8d4f4..edaf622c2c 100644 --- a/cmd/ateapi/internal/apivalidation/zz_generated.validation.go +++ b/cmd/ateapi/internal/apivalidation/zz_generated.validation.go @@ -2449,6 +2449,53 @@ func Validate_CreateAtespaceRequest( return errs } +// Validate_CreateExternalVolumeClassRequest validates an instance of CreateExternalVolumeClassRequest according +// to declarative validation rules in the API schema. +func Validate_CreateExternalVolumeClassRequest( + ctx context.Context, op operation.Operation, fldPath *field.Path, + obj, oldObj *v1.CreateExternalVolumeClassRequest) (errs field.ErrorList) { + + { // field v1.CreateExternalVolumeClassRequest.ExternalVolumeClass + fn := func( + fldPath *field.Path, + obj, oldObj *v1.ExternalVolumeClass, + 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.IfOption(ctx, op, fldPath, obj, oldObj, "ExternalVolumes", false, validate.ForbiddenPointer).MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "ExternalVolumes", false, validate.OptionalPointer).MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + 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_ExternalVolumeClass(ctx, op, fldPath, obj, oldObj)...) + return + } + oldVal := safe.Field(oldObj, + func(oldObj *v1.CreateExternalVolumeClassRequest) *v1.ExternalVolumeClass { + return oldObj.ExternalVolumeClass + }) + errs = append(errs, fn(fldPath.Child("external_volume_class"), obj.ExternalVolumeClass, oldVal, oldObj != nil)...) + } + + return errs +} + // Validate_CreateGlobalAccessPolicyRequest validates an instance of CreateGlobalAccessPolicyRequest according // to declarative validation rules in the API schema. func Validate_CreateGlobalAccessPolicyRequest( @@ -3234,6 +3281,95 @@ func Validate_DeleteAtespaceRequest( return errs } +// Validate_DeleteExternalVolumeClassRequest validates an instance of DeleteExternalVolumeClassRequest according +// to declarative validation rules in the API schema. +func Validate_DeleteExternalVolumeClassRequest( + ctx context.Context, op operation.Operation, fldPath *field.Path, + obj, oldObj *v1.DeleteExternalVolumeClassRequest) (errs field.ErrorList) { + + { // field v1.DeleteExternalVolumeClassRequest.ExternalVolumeClass + fn := func( + fldPath *field.Path, + obj, oldObj *v1.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 *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().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 *v1.DeleteExternalVolumeClassRequest) *v1.ObjectRef { + return oldObj.ExternalVolumeClass + }) + errs = append(errs, fn(fldPath.Child("external_volume_class"), obj.ExternalVolumeClass, oldVal, oldObj != nil)...) + } + + { // field v1.DeleteExternalVolumeClassRequest.Options + fn := func( + fldPath *field.Path, + obj, oldObj *v1.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 *v1.DeleteExternalVolumeClassRequest) *v1.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( @@ -3898,6 +4034,149 @@ func Validate_EnvVar( return errs } +// Validate_ExternalVolumeClass validates an instance of ExternalVolumeClass according +// to declarative validation rules in the API schema. +func Validate_ExternalVolumeClass( + ctx context.Context, op operation.Operation, fldPath *field.Path, + obj, oldObj *v1.ExternalVolumeClass) (errs field.ErrorList) { + + { // field v1.ExternalVolumeClass.Metadata + fn := func( + fldPath *field.Path, + obj, oldObj *v1.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 *v1.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", + func(o *v1.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", + func(o *v1.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.Immutable).MarkBeta().MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", + func(o *v1.ResourceMetadata) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().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 *v1.ExternalVolumeClass) *v1.ResourceMetadata { + return oldObj.Metadata + }) + errs = append(errs, fn(fldPath.Child("metadata"), obj.Metadata, oldVal, oldObj != nil)...) + } + + { // field v1.ExternalVolumeClass.DriverName + 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_ExternalVolumeClass_DriverName(ctx, op, fldPath, obj, oldObj); len(e) != 0 { + errs = append(errs, e...) + } + if e := validate.MaxLength(ctx, op, fldPath, obj, oldObj, 63); len(e) != 0 { + errs = append(errs, e...) + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *v1.ExternalVolumeClass) *string { + return &oldObj.DriverName + }) + errs = append(errs, fn(fldPath.Child("driver_name"), &obj.DriverName, oldVal, oldObj != nil)...) + } + + { // field v1.ExternalVolumeClass.Parameters + 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 *v1.ExternalVolumeClass) map[string]string { + return oldObj.Parameters + }) + errs = append(errs, fn(fldPath.Child("parameters"), obj.Parameters, oldVal, oldObj != nil)...) + } + + return errs +} + var unionMembershipFor_go_ate_dev_substrate_api_ateapi_v1_ExternalVolumeSource_ = validate.NewUnionMembership(validate.NewUnionMember("template")) // Validate_ExternalVolumeSource validates an instance of ExternalVolumeSource according @@ -4591,6 +4870,65 @@ func Validate_GetAtespaceRequest( return errs } +// Validate_GetExternalVolumeClassRequest validates an instance of GetExternalVolumeClassRequest according +// to declarative validation rules in the API schema. +func Validate_GetExternalVolumeClassRequest( + ctx context.Context, op operation.Operation, fldPath *field.Path, + obj, oldObj *v1.GetExternalVolumeClassRequest) (errs field.ErrorList) { + + { // field v1.GetExternalVolumeClassRequest.ExternalVolumeClass + fn := func( + fldPath *field.Path, + obj, oldObj *v1.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 *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().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 *v1.GetExternalVolumeClassRequest) *v1.ObjectRef { + return oldObj.ExternalVolumeClass + }) + errs = append(errs, fn(fldPath.Child("external_volume_class"), obj.ExternalVolumeClass, oldVal, oldObj != nil)...) + } + + return errs +} + // Validate_GetGlobalAccessPolicyRequest validates an instance of GetGlobalAccessPolicyRequest according // to declarative validation rules in the API schema. func Validate_GetGlobalAccessPolicyRequest( @@ -5491,6 +5829,45 @@ func Validate_ListAtespacesRequest( return errs } +// Validate_ListExternalVolumeClassesRequest validates an instance of ListExternalVolumeClassesRequest according +// to declarative validation rules in the API schema. +func Validate_ListExternalVolumeClassesRequest( + ctx context.Context, op operation.Operation, fldPath *field.Path, + obj, oldObj *v1.ListExternalVolumeClassesRequest) (errs field.ErrorList) { + + { // field v1.ListExternalVolumeClassesRequest.Options + fn := func( + fldPath *field.Path, + obj, oldObj *v1.ListOptions, + 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_ListOptions(ctx, op, fldPath, obj, oldObj)...) + return + } + oldVal := safe.Field(oldObj, + func(oldObj *v1.ListExternalVolumeClassesRequest) *v1.ListOptions { + return oldObj.Options + }) + errs = append(errs, fn(fldPath.Child("options"), obj.Options, oldVal, oldObj != nil)...) + } + + return errs +} + // Validate_ListOptions validates an instance of ListOptions according // to declarative validation rules in the API schema. func Validate_ListOptions( diff --git a/cmd/ateapi/internal/authz/registry.go b/cmd/ateapi/internal/authz/registry.go index b4bf601a0e..d8f136b428 100644 --- a/cmd/ateapi/internal/authz/registry.go +++ b/cmd/ateapi/internal/authz/registry.go @@ -88,6 +88,13 @@ func onWorker(relation, name string, fldPath *field.Path) ([]check, field.ErrorL return []check{{relation: relation, object: WorkerObject(name)}}, nil } +func onExternalVolumeClass(relation, name string, fldPath *field.Path) ([]check, field.ErrorList) { + if errs := validateName(name, fldPath); len(errs) > 0 { + return nil, errs + } + return []check{{relation: relation, object: ExternalVolumeClassObject(name)}}, nil +} + // resourceRef identifies an atespaced resource. Both *ateapi.ObjectRef and // *ateapi.ResourceMetadata satisfy it, including as nil pointers. type resourceRef interface { @@ -294,6 +301,20 @@ var defaultRPCPermissions = map[string]rpcRule{ return onWorker(RelationCanListActorAssignments, r.GetWorker().GetName(), field.NewPath("worker", "name")) })), + // External volume classes. Global-scoped like workers. + ateapi.Control_CreateExternalVolumeClass_FullMethodName: rule(checksOf(func(*ateapi.CreateExternalVolumeClassRequest) ([]check, field.ErrorList) { + return onGlobal(RelationCanCreateExternalVolumeClass) + })), + ateapi.Control_ListExternalVolumeClasses_FullMethodName: rule(checksOf(func(*ateapi.ListExternalVolumeClassesRequest) ([]check, field.ErrorList) { + return onGlobal(RelationCanListExternalVolumeClasses) + })), + ateapi.Control_GetExternalVolumeClass_FullMethodName: rule(checksOf(func(r *ateapi.GetExternalVolumeClassRequest) ([]check, field.ErrorList) { + return onExternalVolumeClass(RelationCanGet, r.GetExternalVolumeClass().GetName(), field.NewPath("external_volume_class", "name")) + })), + ateapi.Control_DeleteExternalVolumeClass_FullMethodName: rule(checksOf(func(r *ateapi.DeleteExternalVolumeClassRequest) ([]check, field.ErrorList) { + return onExternalVolumeClass(RelationCanDelete, r.GetExternalVolumeClass().GetName(), field.NewPath("external_volume_class", "name")) + })), + // Actor identity credentials. ateapi.Control_MintActorJwt_FullMethodName: rule(checksOf(func(r *ateapi.MintActorJwtRequest) ([]check, field.ErrorList) { return onActor(RelationCanMintActorJWT, r.GetActor(), field.NewPath("actor")) diff --git a/cmd/ateapi/internal/authz/registry_test.go b/cmd/ateapi/internal/authz/registry_test.go index d12e60e029..d823ca4bd3 100644 --- a/cmd/ateapi/internal/authz/registry_test.go +++ b/cmd/ateapi/internal/authz/registry_test.go @@ -274,6 +274,32 @@ func TestDefaultRPCPermissions(t *testing.T) { want: []check{{RelationCanListActorAssignments, "worker:w-1"}}, }, + // External volume classes. + { + name: "CreateExternalVolumeClass", + fullMethod: ateapi.Control_CreateExternalVolumeClass_FullMethodName, + req: &ateapi.CreateExternalVolumeClassRequest{}, + want: []check{{RelationCanCreateExternalVolumeClass, GlobalRootObject}}, + }, + { + name: "ListExternalVolumeClasses", + fullMethod: ateapi.Control_ListExternalVolumeClasses_FullMethodName, + req: &ateapi.ListExternalVolumeClassesRequest{}, + want: []check{{RelationCanListExternalVolumeClasses, GlobalRootObject}}, + }, + { + name: "GetExternalVolumeClass", + fullMethod: ateapi.Control_GetExternalVolumeClass_FullMethodName, + req: &ateapi.GetExternalVolumeClassRequest{ExternalVolumeClass: &ateapi.ObjectRef{Name: "nfs-gold"}}, + want: []check{{RelationCanGet, "external_volume_class:nfs-gold"}}, + }, + { + name: "DeleteExternalVolumeClass", + fullMethod: ateapi.Control_DeleteExternalVolumeClass_FullMethodName, + req: &ateapi.DeleteExternalVolumeClassRequest{ExternalVolumeClass: &ateapi.ObjectRef{Name: "nfs-gold"}}, + want: []check{{RelationCanDelete, "external_volume_class:nfs-gold"}}, + }, + // Actor identity credentials. { name: "MintActorJWT", @@ -591,6 +617,18 @@ func TestDefaultRPCPermissions_MalformedIdentifierFailsClosed(t *testing.T) { req: &ateapi.ListWorkerActorAssignmentsRequest{Worker: &ateapi.ObjectRef{}}, wantField: "worker.name", }, + { + name: "GetExternalVolumeClass without a class", + fullMethod: ateapi.Control_GetExternalVolumeClass_FullMethodName, + req: &ateapi.GetExternalVolumeClassRequest{}, + wantField: "external_volume_class.name", + }, + { + name: "DeleteExternalVolumeClass with an invalid name", + fullMethod: ateapi.Control_DeleteExternalVolumeClass_FullMethodName, + req: &ateapi.DeleteExternalVolumeClassRequest{ExternalVolumeClass: &ateapi.ObjectRef{Name: "nfs/gold"}}, + wantField: "external_volume_class.name", + }, { name: "MintActorJWT without an actor", fullMethod: ateapi.Control_MintActorJwt_FullMethodName, diff --git a/tools/apitool/internal/examples/grpc/ExternalVolumeClass.yaml b/tools/apitool/internal/examples/grpc/ExternalVolumeClass.yaml new file mode 100644 index 0000000000..1faa0d1b45 --- /dev/null +++ b/tools/apitool/internal/examples/grpc/ExternalVolumeClass.yaml @@ -0,0 +1,23 @@ +# Copyright 2026 The Agent Substrate Authors +# +# 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. +metadata: + name: csi-nfs + uid: 9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d + version: "1" + createTime: "2026-06-01T00:00:00Z" + updateTime: "2026-06-01T00:00:00Z" +driverName: nfs.csi.k8s.io +parameters: + server: nfs-server.default.svc.cluster.local + share: / From 32dddc1a9dee21ea0de6b91f627716c1ae902890 Mon Sep 17 00:00:00 2001 From: Vu Le Date: Mon, 9 Nov 2026 19:02:08 +0000 Subject: [PATCH 07/30] resource model and authorization docs Signed-off-by: Vu Le --- docs/guides/authorization.md | 12 ++++++++++++ docs/reference/resource-model.md | 3 +++ 2 files changed, 15 insertions(+) diff --git a/docs/guides/authorization.md b/docs/guides/authorization.md index 4de4c65184..656ce542b3 100644 --- a/docs/guides/authorization.md +++ b/docs/guides/authorization.md @@ -216,6 +216,18 @@ Workers have no atespace; their permissions come from the global scope. | `DrainWorker` | `can_drain`, the worker | Global owner; `ate-controller` | | `ListWorkerActorAssignments` | `can_list_actor_assignments`, the worker | Global viewer | +### External volume classes + +External volume classes have no atespace; their permissions come from the +global scope. + +| RPC | Permission, on | Allowed for | +|---|---|---| +| `CreateExternalVolumeClass` | `can_create_external_volume_class`, global | Global owner | +| `ListExternalVolumeClasses` | `can_list_external_volume_classes`, global | Global viewer | +| `GetExternalVolumeClass` | `can_get`, the class | Global viewer | +| `DeleteExternalVolumeClass` | `can_delete`, the class | Global owner | + ### WorkerService The interceptor skips these; each handler requires `atelet`'s pod diff --git a/docs/reference/resource-model.md b/docs/reference/resource-model.md index 05fa1136ef..2e52690ec2 100644 --- a/docs/reference/resource-model.md +++ b/docs/reference/resource-model.md @@ -45,6 +45,7 @@ Global │ ├── Actor │ │ └── EgressPolicy "default" subresource (singleton) │ └── Tag +├── ExternalVolumeClass └── Worker └── ActorAssignment subresource (one per hosted Actor, managed by Substrate) ``` @@ -57,6 +58,7 @@ Global | `ActorTemplate` | Atespace | 0..N | Clients | | `Actor` | Atespace | 0..N | Clients | | `Tag` | Atespace | 0..N | Clients | +| `ExternalVolumeClass` | Global | 0..N | Clients | | `Worker` | Global | 0..N | Substrate | ## Subresources @@ -99,6 +101,7 @@ classDiagram class Tag class Worker class ActorAssignment + class ExternalVolumeClass } Atespace "1" *-- "0..1" AtespaceAccessPolicy From 5a58f85aaf4c3ccbf5af3a1eaad9b3077196c94e Mon Sep 17 00:00:00 2001 From: Vu Le Date: Mon, 9 Nov 2026 23:31:23 +0000 Subject: [PATCH 08/30] RPCService and ServiceImpl handlers and serviceStore interface Signed-off-by: Vu Le --- .../controlapi/external_volume_class.go | 82 ++++++++++++++++++- cmd/ateapi/internal/controlapi/service.go | 4 + 2 files changed, 82 insertions(+), 4 deletions(-) diff --git a/cmd/ateapi/internal/controlapi/external_volume_class.go b/cmd/ateapi/internal/controlapi/external_volume_class.go index 68c25dafd6..d32a02a711 100644 --- a/cmd/ateapi/internal/controlapi/external_volume_class.go +++ b/cmd/ateapi/internal/controlapi/external_volume_class.go @@ -16,23 +16,97 @@ package controlapi import ( "context" + "errors" + "fmt" "go.ate.dev/substrate/api/ateapi/v1" + "go.ate.dev/substrate/cmd/ateapi/internal/apivalidation" + "go.ate.dev/substrate/cmd/ateapi/internal/defaults" "go.ate.dev/substrate/cmd/ateapi/internal/store" + "go.ate.dev/substrate/internal/apierror" + "go.ate.dev/substrate/internal/resources" ) +func (s *RPCService) CreateExternalVolumeClass(ctx context.Context, req *ateapi.CreateExternalVolumeClassRequest) (*ateapi.ExternalVolumeClass, error) { + class := req.GetExternalVolumeClass() + if class != nil { // otherwise validation will flag it + scrubResourceMetadataForCreate(class.Metadata) + defaults.Apply(class) + } + if errs := apivalidation.ValidateCreateExternalVolumeClassRequest(ctx, req); len(errs) > 0 { + return nil, resources.ToAPIError(errs) + } + return s.impl.CreateExternalVolumeClass(ctx, class) +} + func (s *ServiceImpl) CreateExternalVolumeClass(ctx context.Context, class *ateapi.ExternalVolumeClass) (*ateapi.ExternalVolumeClass, error) { - return s.store.CreateExternalVolumeClass(ctx, class) + stored, err := s.store.CreateExternalVolumeClass(ctx, class) + if errors.Is(err, store.ErrAlreadyExists) { + return nil, apierror.AlreadyExists("ExternalVolumeClass %s already exists", class.GetMetadata().GetName()) + } else if err != nil { + return nil, fmt.Errorf("while recording external volume class: %w", err) + } + return stored, nil +} + +func (s *RPCService) GetExternalVolumeClass(ctx context.Context, req *ateapi.GetExternalVolumeClassRequest) (*ateapi.ExternalVolumeClass, error) { + if errs := apivalidation.ValidateGetExternalVolumeClassRequest(ctx, req); len(errs) > 0 { + return nil, resources.ToAPIError(errs) + } + return s.impl.GetExternalVolumeClass(ctx, req.GetExternalVolumeClass().GetName()) } func (s *ServiceImpl) GetExternalVolumeClass(ctx context.Context, name string) (*ateapi.ExternalVolumeClass, error) { - return s.store.GetExternalVolumeClass(ctx, name) + class, err := s.store.GetExternalVolumeClass(ctx, name) + if errors.Is(err, store.ErrNotFound) { + return nil, apierror.NotFound("ExternalVolumeClass %s not found", name) + } else if err != nil { + return nil, fmt.Errorf("while getting external volume class from DB: %w", err) + } + return class, nil +} + +func (s *RPCService) ListExternalVolumeClasses(ctx context.Context, req *ateapi.ListExternalVolumeClassesRequest) (*ateapi.ListExternalVolumeClassesResponse, error) { + if errs := apivalidation.ValidateListExternalVolumeClassesRequest(ctx, req); len(errs) > 0 { + return nil, resources.ToAPIError(errs) + } + page, err := s.impl.ListExternalVolumeClasses(ctx, toStoreListOptions(req.GetOptions())) + if err != nil { + return nil, err + } + return &ateapi.ListExternalVolumeClassesResponse{ + ExternalVolumeClasses: page.Items, + NextPageToken: page.NextPageToken, + }, nil } func (s *ServiceImpl) ListExternalVolumeClasses(ctx context.Context, opts store.ListOptions) (store.ListResponse[*ateapi.ExternalVolumeClass], error) { - return s.store.ListExternalVolumeClasses(ctx, opts) + page, err := s.store.ListExternalVolumeClasses(ctx, opts) + if err != nil { + return page, mapListError(fmt.Errorf("while listing external volume classes in db: %w", err)) + } + return page, nil +} + +func (s *RPCService) DeleteExternalVolumeClass(ctx context.Context, req *ateapi.DeleteExternalVolumeClassRequest) (*ateapi.ExternalVolumeClass, error) { + if errs := apivalidation.ValidateDeleteExternalVolumeClassRequest(ctx, req); len(errs) > 0 { + return nil, resources.ToAPIError(errs) + } + return s.impl.DeleteExternalVolumeClass(ctx, req.GetExternalVolumeClass().GetName(), toDeletePreconditions(req.GetOptions())) } func (s *ServiceImpl) DeleteExternalVolumeClass(ctx context.Context, name string, precondition store.DeletePreconditions) (*ateapi.ExternalVolumeClass, error) { - return s.store.DeleteExternalVolumeClass(ctx, name, precondition) + deleted, err := s.store.DeleteExternalVolumeClass(ctx, name, precondition) + switch { + case err == nil: + return deleted, nil + case errors.Is(err, store.ErrNotFound): + return nil, apierror.NotFound("ExternalVolumeClass %s not found", name) + case errors.Is(err, store.ErrUIDConflict): + return nil, apierror.Aborted("ExternalVolumeClass %s does not have uid %s", name, precondition.UID) + case errors.Is(err, store.ErrVersionConflict): + return nil, apierror.Aborted("concurrent update conflict, please retry") + default: + return nil, fmt.Errorf("while deleting external volume class from DB: %w", err) + } } diff --git a/cmd/ateapi/internal/controlapi/service.go b/cmd/ateapi/internal/controlapi/service.go index f67ebcd613..b3ee8de2e6 100644 --- a/cmd/ateapi/internal/controlapi/service.go +++ b/cmd/ateapi/internal/controlapi/service.go @@ -126,6 +126,10 @@ type serviceStore interface { GetAtespace(ctx context.Context, name string) (*ateapi.Atespace, error) ListAtespaces(ctx context.Context, opts store.ListOptions) (store.ListResponse[*ateapi.Atespace], error) DeleteAtespace(ctx context.Context, name string, precondition store.DeletePreconditions) (*ateapi.Atespace, error) + CreateExternalVolumeClass(ctx context.Context, class *ateapi.ExternalVolumeClass) (*ateapi.ExternalVolumeClass, error) + GetExternalVolumeClass(ctx context.Context, name string) (*ateapi.ExternalVolumeClass, error) + ListExternalVolumeClasses(ctx context.Context, opts store.ListOptions) (store.ListResponse[*ateapi.ExternalVolumeClass], error) + DeleteExternalVolumeClass(ctx context.Context, name string, precondition store.DeletePreconditions) (*ateapi.ExternalVolumeClass, error) CreateGlobalAccessPolicy(ctx context.Context, policy *ateapi.AccessPolicy) (*ateapi.AccessPolicy, error) GetGlobalAccessPolicy(ctx context.Context) (*ateapi.AccessPolicy, error) UpdateGlobalAccessPolicy(ctx context.Context, precondition store.Precondition, mutate func(*ateapi.AccessPolicy) error) (*ateapi.AccessPolicy, error) From 1594d1f8d930e775e4803c82123502bb4d2fda7e Mon Sep 17 00:00:00 2001 From: Vu Le Date: Mon, 9 Nov 2026 23:32:08 +0000 Subject: [PATCH 09/30] functionaltest CRUD, precondition, preview-gate and validation tests Signed-off-by: Vu Le --- .../external_volume_class_test.go | 167 ++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 cmd/ateapi/internal/controlapi/functionaltest/external_volume_class_test.go diff --git a/cmd/ateapi/internal/controlapi/functionaltest/external_volume_class_test.go b/cmd/ateapi/internal/controlapi/functionaltest/external_volume_class_test.go new file mode 100644 index 0000000000..db9e1cbec0 --- /dev/null +++ b/cmd/ateapi/internal/controlapi/functionaltest/external_volume_class_test.go @@ -0,0 +1,167 @@ +// Copyright 2026 The Agent Substrate Authors +// +// 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" + "testing" + + "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" + "go.ate.dev/substrate/internal/preview" + "google.golang.org/grpc/codes" + "google.golang.org/protobuf/testing/protocmp" +) + +func newExternalVolumeClass(name string) *ateapi.ExternalVolumeClass { + return &ateapi.ExternalVolumeClass{ + Metadata: &ateapi.ResourceMetadata{Name: name}, + DriverName: "nfs.csi.k8s.io", + Parameters: map[string]string{"server": "nfs.example.com"}, + } +} + +func createExternalVolumeClass(t *testing.T, tc *testContext, name string) *ateapi.ExternalVolumeClass { + t.Helper() + created, err := tc.client.CreateExternalVolumeClass(context.Background(), &ateapi.CreateExternalVolumeClassRequest{ExternalVolumeClass: newExternalVolumeClass(name)}) + if err != nil { + t.Fatalf("CreateExternalVolumeClass(%s) failed: %v", name, err) + } + return created +} + +func TestCreateExternalVolumeClass(t *testing.T) { + preview.InitForTest(t, "ExternalVolumes") + ns := namespaceForTest("ns-create-evc") + tc := setupPreviewTest(t, ns) + defer tc.cleanup() + ctx := context.Background() + + in := newExternalVolumeClass("nfs") + in.Metadata.Uid = "caller-supplied-uid" + in.Metadata.Version = 999 + created, err := tc.client.CreateExternalVolumeClass(ctx, &ateapi.CreateExternalVolumeClassRequest{ExternalVolumeClass: in}) + if err != nil { + t.Fatalf("CreateExternalVolumeClass failed: %v", err) + } + if diff := cmp.Diff(newExternalVolumeClass("nfs"), created, protocmp.Transform(), ignoreServerMetadata, ignoreVersion); diff != "" { + t.Errorf("CreateExternalVolumeClass mismatch (-want +got):\n%s", diff) + } + if md := created.GetMetadata(); md.GetVersion() != 1 || md.GetUid() == "" || md.GetUid() == "caller-supplied-uid" { + t.Errorf("metadata = %v, want server-assigned uid and version 1", md) + } + + got, err := tc.client.GetExternalVolumeClass(ctx, &ateapi.GetExternalVolumeClassRequest{ExternalVolumeClass: &ateapi.ObjectRef{Name: "nfs"}}) + if err != nil { + t.Fatalf("GetExternalVolumeClass failed: %v", err) + } + if diff := cmp.Diff(created, got, protocmp.Transform()); diff != "" { + t.Errorf("GetExternalVolumeClass mismatch (-created +got):\n%s", diff) + } + + _, err = tc.client.CreateExternalVolumeClass(ctx, &ateapi.CreateExternalVolumeClassRequest{ExternalVolumeClass: newExternalVolumeClass("nfs")}) + assertGrpcError(t, err, codes.AlreadyExists, "ExternalVolumeClass nfs already exists") + + // A client that does not opt in to preview features cannot set the field. + _, err = tc.noOptInClient.CreateExternalVolumeClass(ctx, &ateapi.CreateExternalVolumeClassRequest{ExternalVolumeClass: newExternalVolumeClass("other")}) + assertGrpcErrorRegex(t, err, codes.InvalidArgument, "external_volume_class: Forbidden") +} + +func TestListExternalVolumeClasses(t *testing.T) { + preview.InitForTest(t, "ExternalVolumes") + ns := namespaceForTest("ns-list-evc") + tc := setupPreviewTest(t, ns) + defer tc.cleanup() + + want := []string{"class-a", "class-b", "class-c"} + for _, n := range want { + createExternalVolumeClass(t, tc, n) + } + var got []string + token := "" + for { + resp, err := tc.client.ListExternalVolumeClasses(context.Background(), &ateapi.ListExternalVolumeClassesRequest{Options: &ateapi.ListOptions{PageSize: 2, PageToken: token}}) + if err != nil { + t.Fatalf("ListExternalVolumeClasses failed: %v", err) + } + for _, c := range resp.GetExternalVolumeClasses() { + got = append(got, c.GetMetadata().GetName()) + } + if token = resp.GetNextPageToken(); token == "" { + break + } + } + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("listed classes mismatch (-want +got):\n%s", diff) + } +} + +func TestDeleteExternalVolumeClass(t *testing.T) { + preview.InitForTest(t, "ExternalVolumes") + ns := namespaceForTest("ns-delete-evc") + tc := setupPreviewTest(t, ns) + defer tc.cleanup() + ctx := context.Background() + ref := &ateapi.ObjectRef{Name: "nfs"} + del := func(opts *ateapi.DeleteOptions) (*ateapi.ExternalVolumeClass, error) { + return tc.client.DeleteExternalVolumeClass(ctx, &ateapi.DeleteExternalVolumeClassRequest{ExternalVolumeClass: ref, Options: opts}) + } + + created := createExternalVolumeClass(t, tc, "nfs") + uid, version := created.GetMetadata().GetUid(), created.GetMetadata().GetVersion() + _, err := del(&ateapi.DeleteOptions{Uid: uid, Version: version + 1}) + assertGrpcError(t, err, codes.Aborted, "concurrent update conflict, please retry") + _, err = del(&ateapi.DeleteOptions{Uid: foreignUID}) + assertGrpcError(t, err, codes.Aborted, "ExternalVolumeClass nfs does not have uid "+foreignUID) + + deleted, err := del(&ateapi.DeleteOptions{Uid: uid, Version: version}) + if err != nil { + t.Fatalf("DeleteExternalVolumeClass failed: %v", err) + } + if deleted.GetMetadata().GetName() != "nfs" || deleted.GetMetadata().GetDeleteTime() == nil { + t.Errorf("deleted class = %v, want nfs with delete_time", deleted.GetMetadata()) + } + _, err = tc.client.GetExternalVolumeClass(ctx, &ateapi.GetExternalVolumeClassRequest{ExternalVolumeClass: ref}) + assertGrpcError(t, err, codes.NotFound, "ExternalVolumeClass nfs not found") + _, err = del(nil) + assertGrpcError(t, err, codes.NotFound, "ExternalVolumeClass nfs not found") +} + +func TestValidation_ExternalVolumeClass(t *testing.T) { + preview.InitForTest(t, "ExternalVolumes") + ns := namespaceForTest("ns-validation-evc") + tc := setupPreviewTest(t, ns) + defer tc.cleanup() + ctx := context.Background() + + t.Run("CreateExternalVolumeClass", func(t *testing.T) { + bad := newExternalVolumeClass("nfs") + bad.DriverName = "Bad_Driver" + _, err := tc.client.CreateExternalVolumeClass(ctx, &ateapi.CreateExternalVolumeClassRequest{ExternalVolumeClass: bad}) + assertGrpcErrorRegex(t, err, codes.InvalidArgument, "driver_name: Invalid value") + }) + t.Run("GetExternalVolumeClass", func(t *testing.T) { + _, err := tc.client.GetExternalVolumeClass(ctx, &ateapi.GetExternalVolumeClassRequest{}) + assertGrpcErrorRegex(t, err, codes.InvalidArgument, "external_volume_class: Required value") + }) + t.Run("ListExternalVolumeClasses", func(t *testing.T) { + _, err := tc.client.ListExternalVolumeClasses(ctx, &ateapi.ListExternalVolumeClassesRequest{Options: &ateapi.ListOptions{PageSize: -1}}) + assertGrpcErrorRegex(t, err, codes.InvalidArgument, "page_size: Invalid value") + }) + t.Run("DeleteExternalVolumeClass", func(t *testing.T) { + _, err := tc.client.DeleteExternalVolumeClass(ctx, &ateapi.DeleteExternalVolumeClassRequest{}) + assertGrpcErrorRegex(t, err, codes.InvalidArgument, "external_volume_class: Required value") + }) +} From f60f6a6b13e45ca99d177540e7c1437f8f2690b1 Mon Sep 17 00:00:00 2001 From: Vu Le Date: Tue, 10 Nov 2026 00:34:32 +0000 Subject: [PATCH 10/30] ExternalVolumeTemplate field, union validation, and validation tests Signed-off-by: Vu Le --- api/ateapi/v1/ateapi.pb.go | 519 +++++++++--------- api/ateapi/v1/ateapi.proto | 15 +- .../apivalidation/actor_template_test.go | 32 +- .../apivalidation/zz_generated.validation.go | 71 ++- 4 files changed, 381 insertions(+), 256 deletions(-) diff --git a/api/ateapi/v1/ateapi.pb.go b/api/ateapi/v1/ateapi.pb.go index 9228052ceb..8c46c8a616 100644 --- a/api/ateapi/v1/ateapi.pb.go +++ b/api/ateapi/v1/ateapi.pb.go @@ -3994,13 +3994,23 @@ type ExternalVolumeTemplate struct { // +k8s:minimum=1 CapacityBytes int64 `protobuf:"varint,1,opt,name=capacity_bytes,json=capacityBytes,proto3" json:"capacity_bytes,omitempty"` // storage_class_name names the cluster-scoped Kubernetes StorageClass to - // create the volume from. Required. + // create the volume from. Prefer external_volume_class. // - // +k8s:required + // Exactly one of storage_class_name and external_volume_class must be set. + // + // +k8s:optional + // +k8s:unionMember // +k8s:format=k8s-long-name StorageClassName string `protobuf:"bytes,2,opt,name=storage_class_name,json=storageClassName,proto3" json:"storage_class_name,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // external_volume_class names the ExternalVolumeClass to create the volume + // from. atespace must be empty. + // + // +k8s:optional + // +k8s:unionMember + // +k8s:beta(since: "0.0")=+k8s:subfield(atespace)=+k8s:forbidden # TODO: get rid of beta prefix + ExternalVolumeClass *ObjectRef `protobuf:"bytes,3,opt,name=external_volume_class,json=externalVolumeClass,proto3" json:"external_volume_class,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *ExternalVolumeTemplate) Reset() { @@ -4047,6 +4057,13 @@ func (x *ExternalVolumeTemplate) GetStorageClassName() string { return "" } +func (x *ExternalVolumeTemplate) GetExternalVolumeClass() *ObjectRef { + if x != nil { + return x.ExternalVolumeClass + } + return nil +} + // ExternalVolumeClass names the CSI driver that provisions external volumes // and the parameters for its CreateVolume call. Global-scoped and immutable: // metadata.atespace must be empty. @@ -10538,10 +10555,11 @@ const file_api_ateapi_v1_ateapi_proto_rawDesc = "" + "\btemplate\x18\x01 \x01(\v2+.substrate.ateapi.v1.ExternalVolumeTemplateR\btemplate\"1\n" + "\x11ImageVolumeSource\x12\x1c\n" + "\treference\x18\x01 \x01(\tR\treference\"\x18\n" + - "\x16DurableDirVolumeSource\"m\n" + + "\x16DurableDirVolumeSource\"\xc1\x01\n" + "\x16ExternalVolumeTemplate\x12%\n" + "\x0ecapacity_bytes\x18\x01 \x01(\x03R\rcapacityBytes\x12,\n" + - "\x12storage_class_name\x18\x02 \x01(\tR\x10storageClassName\"\xb1\x02\n" + + "\x12storage_class_name\x18\x02 \x01(\tR\x10storageClassName\x12R\n" + + "\x15external_volume_class\x18\x03 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x13externalVolumeClass\"\xb1\x02\n" + "\x13ExternalVolumeClass\x12A\n" + "\bmetadata\x18\x01 \x01(\v2%.substrate.ateapi.v1.ResourceMetadataR\bmetadata\x12\x1f\n" + "\vdriver_name\x18\x02 \x01(\tR\n" + @@ -11276,250 +11294,251 @@ var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 55, // 69: substrate.ateapi.v1.Volume.system_info:type_name -> substrate.ateapi.v1.SystemInfoVolumeSource 51, // 70: substrate.ateapi.v1.Volume.image:type_name -> substrate.ateapi.v1.ImageVolumeSource 53, // 71: substrate.ateapi.v1.ExternalVolumeSource.template:type_name -> substrate.ateapi.v1.ExternalVolumeTemplate - 14, // 72: substrate.ateapi.v1.ExternalVolumeClass.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata - 158, // 73: substrate.ateapi.v1.ExternalVolumeClass.parameters:type_name -> substrate.ateapi.v1.ExternalVolumeClass.ParametersEntry - 56, // 74: substrate.ateapi.v1.SystemInfoVolumeSource.data_sources:type_name -> substrate.ateapi.v1.SystemInfoDataSource - 57, // 75: substrate.ateapi.v1.SystemInfoDataSource.actor_metadata:type_name -> substrate.ateapi.v1.ActorMetadataDataSource - 59, // 76: substrate.ateapi.v1.SystemInfoDataSource.trust_bundle:type_name -> substrate.ateapi.v1.TrustBundleDataSource - 58, // 77: substrate.ateapi.v1.ActorMetadataDataSource.items:type_name -> substrate.ateapi.v1.ActorMetadataItem - 6, // 78: substrate.ateapi.v1.ActorMetadataItem.field:type_name -> substrate.ateapi.v1.ActorMetadataField - 34, // 79: substrate.ateapi.v1.CreateAtespaceRequest.atespace:type_name -> substrate.ateapi.v1.Atespace - 35, // 80: substrate.ateapi.v1.GetAtespaceRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef - 100, // 81: substrate.ateapi.v1.ListAtespacesRequest.options:type_name -> substrate.ateapi.v1.ListOptions - 34, // 82: substrate.ateapi.v1.ListAtespacesResponse.atespaces:type_name -> substrate.ateapi.v1.Atespace - 35, // 83: substrate.ateapi.v1.DeleteAtespaceRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef - 99, // 84: substrate.ateapi.v1.DeleteAtespaceRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions - 54, // 85: substrate.ateapi.v1.CreateExternalVolumeClassRequest.external_volume_class:type_name -> substrate.ateapi.v1.ExternalVolumeClass - 35, // 86: substrate.ateapi.v1.GetExternalVolumeClassRequest.external_volume_class:type_name -> substrate.ateapi.v1.ObjectRef - 100, // 87: substrate.ateapi.v1.ListExternalVolumeClassesRequest.options:type_name -> substrate.ateapi.v1.ListOptions - 54, // 88: substrate.ateapi.v1.ListExternalVolumeClassesResponse.external_volume_classes:type_name -> substrate.ateapi.v1.ExternalVolumeClass - 35, // 89: substrate.ateapi.v1.DeleteExternalVolumeClassRequest.external_volume_class:type_name -> substrate.ateapi.v1.ObjectRef - 99, // 90: substrate.ateapi.v1.DeleteExternalVolumeClassRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions - 36, // 91: substrate.ateapi.v1.CreateActorTemplateRequest.actor_template:type_name -> substrate.ateapi.v1.ActorTemplate - 35, // 92: substrate.ateapi.v1.GetActorTemplateRequest.actor_template:type_name -> substrate.ateapi.v1.ObjectRef - 100, // 93: substrate.ateapi.v1.ListActorTemplatesRequest.options:type_name -> substrate.ateapi.v1.ListOptions - 36, // 94: substrate.ateapi.v1.ListActorTemplatesResponse.actor_templates:type_name -> substrate.ateapi.v1.ActorTemplate - 35, // 95: substrate.ateapi.v1.DeleteActorTemplateRequest.actor_template:type_name -> substrate.ateapi.v1.ObjectRef - 99, // 96: substrate.ateapi.v1.DeleteActorTemplateRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions - 35, // 97: substrate.ateapi.v1.GetActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 17, // 98: substrate.ateapi.v1.CreateActorRequest.actor:type_name -> substrate.ateapi.v1.Actor - 17, // 99: substrate.ateapi.v1.UpdateActorRequest.actor:type_name -> substrate.ateapi.v1.Actor - 35, // 100: substrate.ateapi.v1.SuspendActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 81, // 101: substrate.ateapi.v1.SuspendActorRequest.options:type_name -> substrate.ateapi.v1.SuspendOptions - 17, // 102: substrate.ateapi.v1.SuspendActorResponse.actor:type_name -> substrate.ateapi.v1.Actor - 7, // 103: substrate.ateapi.v1.SuspendOptions.mode:type_name -> substrate.ateapi.v1.DurabilityMode - 35, // 104: substrate.ateapi.v1.ResumeActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 17, // 105: substrate.ateapi.v1.ResumeActorResponse.actor:type_name -> substrate.ateapi.v1.Actor - 35, // 106: substrate.ateapi.v1.RevertActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 17, // 107: substrate.ateapi.v1.RevertActorResponse.actor:type_name -> substrate.ateapi.v1.Actor - 35, // 108: substrate.ateapi.v1.DeleteActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 99, // 109: substrate.ateapi.v1.DeleteActorRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions - 35, // 110: substrate.ateapi.v1.GetActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 111: substrate.ateapi.v1.CreateActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 18, // 112: substrate.ateapi.v1.CreateActorEgressPolicyRequest.egress_policy:type_name -> substrate.ateapi.v1.EgressPolicy - 35, // 113: substrate.ateapi.v1.UpdateActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 18, // 114: substrate.ateapi.v1.UpdateActorEgressPolicyRequest.egress_policy:type_name -> substrate.ateapi.v1.EgressPolicy - 35, // 115: substrate.ateapi.v1.DeleteActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 99, // 116: substrate.ateapi.v1.DeleteActorEgressPolicyRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions - 35, // 117: substrate.ateapi.v1.GetTagRequest.tag:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 118: substrate.ateapi.v1.MintActorJwtRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 160, // 119: substrate.ateapi.v1.MintActorJwtResponse.expire_time:type_name -> google.protobuf.Timestamp - 100, // 120: substrate.ateapi.v1.ListTagsRequest.options:type_name -> substrate.ateapi.v1.ListOptions - 33, // 121: substrate.ateapi.v1.ListTagsResponse.tags:type_name -> substrate.ateapi.v1.Tag - 33, // 122: substrate.ateapi.v1.CreateTagRequest.tag:type_name -> substrate.ateapi.v1.Tag - 33, // 123: substrate.ateapi.v1.UpdateTagRequest.tag:type_name -> substrate.ateapi.v1.Tag - 35, // 124: substrate.ateapi.v1.DeleteTagRequest.tag:type_name -> substrate.ateapi.v1.ObjectRef - 99, // 125: substrate.ateapi.v1.DeleteTagRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions - 35, // 126: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 100, // 127: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest.options:type_name -> substrate.ateapi.v1.ListOptions - 126, // 128: substrate.ateapi.v1.ListWorkerActorAssignmentsResponse.actor_assignments:type_name -> substrate.ateapi.v1.ActorAssignment - 100, // 129: substrate.ateapi.v1.ListWorkersRequest.options:type_name -> substrate.ateapi.v1.ListOptions - 117, // 130: substrate.ateapi.v1.ListWorkersResponse.workers:type_name -> substrate.ateapi.v1.Worker - 35, // 131: substrate.ateapi.v1.GetWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 117, // 132: substrate.ateapi.v1.CreateWorkerRequest.worker:type_name -> substrate.ateapi.v1.Worker - 117, // 133: substrate.ateapi.v1.UpdateWorkerRequest.worker:type_name -> substrate.ateapi.v1.Worker - 35, // 134: substrate.ateapi.v1.DeleteWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 99, // 135: substrate.ateapi.v1.DeleteWorkerRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions - 35, // 136: substrate.ateapi.v1.DrainWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 117, // 137: substrate.ateapi.v1.DrainWorkerResponse.worker:type_name -> substrate.ateapi.v1.Worker - 35, // 138: substrate.ateapi.v1.MarkWorkerAvailableRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 117, // 139: substrate.ateapi.v1.MarkWorkerAvailableResponse.worker:type_name -> substrate.ateapi.v1.Worker - 35, // 140: substrate.ateapi.v1.MarkWorkerUnavailableRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 117, // 141: substrate.ateapi.v1.MarkWorkerUnavailableResponse.worker:type_name -> substrate.ateapi.v1.Worker - 100, // 142: substrate.ateapi.v1.ListActorsRequest.options:type_name -> substrate.ateapi.v1.ListOptions - 17, // 143: substrate.ateapi.v1.ListActorsResponse.actors:type_name -> substrate.ateapi.v1.Actor - 14, // 144: substrate.ateapi.v1.Worker.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata - 159, // 145: substrate.ateapi.v1.Worker.labels:type_name -> substrate.ateapi.v1.Worker.LabelsEntry - 118, // 146: substrate.ateapi.v1.Worker.status:type_name -> substrate.ateapi.v1.WorkerStatus - 8, // 147: substrate.ateapi.v1.WorkerStatus.state:type_name -> substrate.ateapi.v1.WorkerState - 125, // 148: substrate.ateapi.v1.WorkerStatus.capacity:type_name -> substrate.ateapi.v1.WorkerResources - 125, // 149: substrate.ateapi.v1.WorkerStatus.allocated:type_name -> substrate.ateapi.v1.WorkerResources - 119, // 150: substrate.ateapi.v1.WorkerStatus.sandbox_classes:type_name -> substrate.ateapi.v1.WorkerSandboxClass - 120, // 151: substrate.ateapi.v1.WorkerSandboxClass.default_runtime:type_name -> substrate.ateapi.v1.WorkerSandboxRuntime - 120, // 152: substrate.ateapi.v1.WorkerSandboxClass.restorable_runtimes:type_name -> substrate.ateapi.v1.WorkerSandboxRuntime - 123, // 153: substrate.ateapi.v1.WorkerSandboxRuntime.version:type_name -> substrate.ateapi.v1.VersionedSandboxCompat - 121, // 154: substrate.ateapi.v1.WorkerSandboxRuntime.actor_overhead:type_name -> substrate.ateapi.v1.RuntimeOverhead - 123, // 155: substrate.ateapi.v1.ActorSandboxRuntime.version:type_name -> substrate.ateapi.v1.VersionedSandboxCompat - 124, // 156: substrate.ateapi.v1.VersionedSandboxCompat.attributes:type_name -> substrate.ateapi.v1.AttributeEntry - 14, // 157: substrate.ateapi.v1.ActorAssignment.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata - 35, // 158: substrate.ateapi.v1.ActorAssignment.actor:type_name -> substrate.ateapi.v1.ObjectRef - 38, // 159: substrate.ateapi.v1.ActorAssignment.resources:type_name -> substrate.ateapi.v1.Resources - 35, // 160: substrate.ateapi.v1.AcquireWorkerEpochRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 161: substrate.ateapi.v1.RegisterWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 125, // 162: substrate.ateapi.v1.RegisterWorkerRequest.capacity:type_name -> substrate.ateapi.v1.WorkerResources - 117, // 163: substrate.ateapi.v1.RegisterWorkerResponse.worker:type_name -> substrate.ateapi.v1.Worker - 35, // 164: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 119, // 165: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest.sandbox_classes:type_name -> substrate.ateapi.v1.WorkerSandboxClass - 117, // 166: substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse.worker:type_name -> substrate.ateapi.v1.Worker - 35, // 167: substrate.ateapi.v1.MintWorkerActorCertificateRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 168: substrate.ateapi.v1.MintWorkerActorCertificateRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 169: substrate.ateapi.v1.MintWorkerActorJwtRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 160, // 170: substrate.ateapi.v1.MintWorkerActorJwtResponse.expire_time:type_name -> google.protobuf.Timestamp - 35, // 171: substrate.ateapi.v1.RequestActorSuspendRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 172: substrate.ateapi.v1.RequestActorSuspendRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 17, // 173: substrate.ateapi.v1.RequestActorSuspendResponse.actor:type_name -> substrate.ateapi.v1.Actor - 35, // 174: substrate.ateapi.v1.ReportActorCrashedRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 175: substrate.ateapi.v1.ReportActorCrashedRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 17, // 176: substrate.ateapi.v1.ReportActorCrashedResponse.actor:type_name -> substrate.ateapi.v1.Actor - 35, // 177: substrate.ateapi.v1.ReportActorSnapshotStateRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 143, // 178: substrate.ateapi.v1.ReportActorSnapshotStateRequest.state:type_name -> substrate.ateapi.v1.ActorSnapshotState - 144, // 179: substrate.ateapi.v1.ActorSnapshotState.latest_local:type_name -> substrate.ateapi.v1.SnapshotReport - 144, // 180: substrate.ateapi.v1.ActorSnapshotState.uploading:type_name -> substrate.ateapi.v1.SnapshotReport - 144, // 181: substrate.ateapi.v1.ActorSnapshotState.latest_durable:type_name -> substrate.ateapi.v1.SnapshotReport - 160, // 182: substrate.ateapi.v1.ActorSnapshotState.upload_due_time:type_name -> google.protobuf.Timestamp - 2, // 183: substrate.ateapi.v1.SnapshotReport.fidelity:type_name -> substrate.ateapi.v1.SnapshotFidelity - 10, // 184: substrate.ateapi.v1.SnapshotReport.object:type_name -> substrate.ateapi.v1.ObjectSnapshot - 160, // 185: substrate.ateapi.v1.SnapshotReport.local_commit_time:type_name -> google.protobuf.Timestamp - 160, // 186: substrate.ateapi.v1.SnapshotReport.durable_complete_time:type_name -> google.protobuf.Timestamp - 14, // 187: substrate.ateapi.v1.AccessPolicy.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata - 146, // 188: substrate.ateapi.v1.AccessPolicy.bindings:type_name -> substrate.ateapi.v1.Binding - 145, // 189: substrate.ateapi.v1.CreateGlobalAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy - 145, // 190: substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy - 35, // 191: substrate.ateapi.v1.GetAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef - 35, // 192: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef - 145, // 193: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy - 35, // 194: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef - 145, // 195: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy - 35, // 196: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef - 99, // 197: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions - 9, // 198: substrate.ateapi.v1.ResourceAnnotation.scope:type_name -> substrate.ateapi.v1.Scope - 161, // 199: substrate.ateapi.v1.resource:extendee -> google.protobuf.MessageOptions - 162, // 200: substrate.ateapi.v1.method:extendee -> google.protobuf.MethodOptions - 154, // 201: substrate.ateapi.v1.resource:type_name -> substrate.ateapi.v1.ResourceAnnotation - 155, // 202: substrate.ateapi.v1.method:type_name -> substrate.ateapi.v1.MethodAnnotation - 76, // 203: substrate.ateapi.v1.Control.GetActor:input_type -> substrate.ateapi.v1.GetActorRequest - 77, // 204: substrate.ateapi.v1.Control.CreateActor:input_type -> substrate.ateapi.v1.CreateActorRequest - 78, // 205: substrate.ateapi.v1.Control.UpdateActor:input_type -> substrate.ateapi.v1.UpdateActorRequest - 79, // 206: substrate.ateapi.v1.Control.SuspendActor:input_type -> substrate.ateapi.v1.SuspendActorRequest - 82, // 207: substrate.ateapi.v1.Control.ResumeActor:input_type -> substrate.ateapi.v1.ResumeActorRequest - 84, // 208: substrate.ateapi.v1.Control.RevertActor:input_type -> substrate.ateapi.v1.RevertActorRequest - 86, // 209: substrate.ateapi.v1.Control.DeleteActor:input_type -> substrate.ateapi.v1.DeleteActorRequest - 87, // 210: substrate.ateapi.v1.Control.GetActorEgressPolicy:input_type -> substrate.ateapi.v1.GetActorEgressPolicyRequest - 88, // 211: substrate.ateapi.v1.Control.CreateActorEgressPolicy:input_type -> substrate.ateapi.v1.CreateActorEgressPolicyRequest - 89, // 212: substrate.ateapi.v1.Control.UpdateActorEgressPolicy:input_type -> substrate.ateapi.v1.UpdateActorEgressPolicyRequest - 90, // 213: substrate.ateapi.v1.Control.DeleteActorEgressPolicy:input_type -> substrate.ateapi.v1.DeleteActorEgressPolicyRequest - 92, // 214: substrate.ateapi.v1.Control.MintActorJwt:input_type -> substrate.ateapi.v1.MintActorJwtRequest - 96, // 215: substrate.ateapi.v1.Control.CreateTag:input_type -> substrate.ateapi.v1.CreateTagRequest - 91, // 216: substrate.ateapi.v1.Control.GetTag:input_type -> substrate.ateapi.v1.GetTagRequest - 94, // 217: substrate.ateapi.v1.Control.ListTags:input_type -> substrate.ateapi.v1.ListTagsRequest - 97, // 218: substrate.ateapi.v1.Control.UpdateTag:input_type -> substrate.ateapi.v1.UpdateTagRequest - 98, // 219: substrate.ateapi.v1.Control.DeleteTag:input_type -> substrate.ateapi.v1.DeleteTagRequest - 103, // 220: substrate.ateapi.v1.Control.ListWorkers:input_type -> substrate.ateapi.v1.ListWorkersRequest - 105, // 221: substrate.ateapi.v1.Control.GetWorker:input_type -> substrate.ateapi.v1.GetWorkerRequest - 106, // 222: substrate.ateapi.v1.Control.CreateWorker:input_type -> substrate.ateapi.v1.CreateWorkerRequest - 107, // 223: substrate.ateapi.v1.Control.UpdateWorker:input_type -> substrate.ateapi.v1.UpdateWorkerRequest - 108, // 224: substrate.ateapi.v1.Control.DeleteWorker:input_type -> substrate.ateapi.v1.DeleteWorkerRequest - 109, // 225: substrate.ateapi.v1.Control.DrainWorker:input_type -> substrate.ateapi.v1.DrainWorkerRequest - 111, // 226: substrate.ateapi.v1.Control.MarkWorkerAvailable:input_type -> substrate.ateapi.v1.MarkWorkerAvailableRequest - 113, // 227: substrate.ateapi.v1.Control.MarkWorkerUnavailable:input_type -> substrate.ateapi.v1.MarkWorkerUnavailableRequest - 101, // 228: substrate.ateapi.v1.Control.ListWorkerActorAssignments:input_type -> substrate.ateapi.v1.ListWorkerActorAssignmentsRequest - 115, // 229: substrate.ateapi.v1.Control.ListActors:input_type -> substrate.ateapi.v1.ListActorsRequest - 61, // 230: substrate.ateapi.v1.Control.CreateAtespace:input_type -> substrate.ateapi.v1.CreateAtespaceRequest - 62, // 231: substrate.ateapi.v1.Control.GetAtespace:input_type -> substrate.ateapi.v1.GetAtespaceRequest - 63, // 232: substrate.ateapi.v1.Control.ListAtespaces:input_type -> substrate.ateapi.v1.ListAtespacesRequest - 65, // 233: substrate.ateapi.v1.Control.DeleteAtespace:input_type -> substrate.ateapi.v1.DeleteAtespaceRequest - 66, // 234: substrate.ateapi.v1.Control.CreateExternalVolumeClass:input_type -> substrate.ateapi.v1.CreateExternalVolumeClassRequest - 67, // 235: substrate.ateapi.v1.Control.GetExternalVolumeClass:input_type -> substrate.ateapi.v1.GetExternalVolumeClassRequest - 68, // 236: substrate.ateapi.v1.Control.ListExternalVolumeClasses:input_type -> substrate.ateapi.v1.ListExternalVolumeClassesRequest - 70, // 237: substrate.ateapi.v1.Control.DeleteExternalVolumeClass:input_type -> substrate.ateapi.v1.DeleteExternalVolumeClassRequest - 71, // 238: substrate.ateapi.v1.Control.CreateActorTemplate:input_type -> substrate.ateapi.v1.CreateActorTemplateRequest - 72, // 239: substrate.ateapi.v1.Control.GetActorTemplate:input_type -> substrate.ateapi.v1.GetActorTemplateRequest - 73, // 240: substrate.ateapi.v1.Control.ListActorTemplates:input_type -> substrate.ateapi.v1.ListActorTemplatesRequest - 75, // 241: substrate.ateapi.v1.Control.DeleteActorTemplate:input_type -> substrate.ateapi.v1.DeleteActorTemplateRequest - 147, // 242: substrate.ateapi.v1.Control.GetGlobalAccessPolicy:input_type -> substrate.ateapi.v1.GetGlobalAccessPolicyRequest - 148, // 243: substrate.ateapi.v1.Control.CreateGlobalAccessPolicy:input_type -> substrate.ateapi.v1.CreateGlobalAccessPolicyRequest - 149, // 244: substrate.ateapi.v1.Control.UpdateGlobalAccessPolicy:input_type -> substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest - 150, // 245: substrate.ateapi.v1.Control.GetAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.GetAtespaceAccessPolicyRequest - 151, // 246: substrate.ateapi.v1.Control.CreateAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest - 152, // 247: substrate.ateapi.v1.Control.UpdateAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest - 153, // 248: substrate.ateapi.v1.Control.DeleteAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest - 127, // 249: substrate.ateapi.v1.WorkerService.AcquireWorkerEpoch:input_type -> substrate.ateapi.v1.AcquireWorkerEpochRequest - 129, // 250: substrate.ateapi.v1.WorkerService.RegisterWorker:input_type -> substrate.ateapi.v1.RegisterWorkerRequest - 131, // 251: substrate.ateapi.v1.WorkerService.SetWorkerSandboxRuntimes:input_type -> substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest - 133, // 252: substrate.ateapi.v1.WorkerService.MintWorkerActorCertificate:input_type -> substrate.ateapi.v1.MintWorkerActorCertificateRequest - 135, // 253: substrate.ateapi.v1.WorkerService.MintWorkerActorJwt:input_type -> substrate.ateapi.v1.MintWorkerActorJwtRequest - 137, // 254: substrate.ateapi.v1.WorkerService.RequestActorSuspend:input_type -> substrate.ateapi.v1.RequestActorSuspendRequest - 141, // 255: substrate.ateapi.v1.WorkerService.ReportActorSnapshotState:input_type -> substrate.ateapi.v1.ReportActorSnapshotStateRequest - 139, // 256: substrate.ateapi.v1.WorkerService.ReportActorCrashed:input_type -> substrate.ateapi.v1.ReportActorCrashedRequest - 17, // 257: substrate.ateapi.v1.Control.GetActor:output_type -> substrate.ateapi.v1.Actor - 17, // 258: substrate.ateapi.v1.Control.CreateActor:output_type -> substrate.ateapi.v1.Actor - 17, // 259: substrate.ateapi.v1.Control.UpdateActor:output_type -> substrate.ateapi.v1.Actor - 80, // 260: substrate.ateapi.v1.Control.SuspendActor:output_type -> substrate.ateapi.v1.SuspendActorResponse - 83, // 261: substrate.ateapi.v1.Control.ResumeActor:output_type -> substrate.ateapi.v1.ResumeActorResponse - 85, // 262: substrate.ateapi.v1.Control.RevertActor:output_type -> substrate.ateapi.v1.RevertActorResponse - 17, // 263: substrate.ateapi.v1.Control.DeleteActor:output_type -> substrate.ateapi.v1.Actor - 18, // 264: substrate.ateapi.v1.Control.GetActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy - 18, // 265: substrate.ateapi.v1.Control.CreateActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy - 18, // 266: substrate.ateapi.v1.Control.UpdateActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy - 18, // 267: substrate.ateapi.v1.Control.DeleteActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy - 93, // 268: substrate.ateapi.v1.Control.MintActorJwt:output_type -> substrate.ateapi.v1.MintActorJwtResponse - 33, // 269: substrate.ateapi.v1.Control.CreateTag:output_type -> substrate.ateapi.v1.Tag - 33, // 270: substrate.ateapi.v1.Control.GetTag:output_type -> substrate.ateapi.v1.Tag - 95, // 271: substrate.ateapi.v1.Control.ListTags:output_type -> substrate.ateapi.v1.ListTagsResponse - 33, // 272: substrate.ateapi.v1.Control.UpdateTag:output_type -> substrate.ateapi.v1.Tag - 33, // 273: substrate.ateapi.v1.Control.DeleteTag:output_type -> substrate.ateapi.v1.Tag - 104, // 274: substrate.ateapi.v1.Control.ListWorkers:output_type -> substrate.ateapi.v1.ListWorkersResponse - 117, // 275: substrate.ateapi.v1.Control.GetWorker:output_type -> substrate.ateapi.v1.Worker - 117, // 276: substrate.ateapi.v1.Control.CreateWorker:output_type -> substrate.ateapi.v1.Worker - 117, // 277: substrate.ateapi.v1.Control.UpdateWorker:output_type -> substrate.ateapi.v1.Worker - 117, // 278: substrate.ateapi.v1.Control.DeleteWorker:output_type -> substrate.ateapi.v1.Worker - 110, // 279: substrate.ateapi.v1.Control.DrainWorker:output_type -> substrate.ateapi.v1.DrainWorkerResponse - 112, // 280: substrate.ateapi.v1.Control.MarkWorkerAvailable:output_type -> substrate.ateapi.v1.MarkWorkerAvailableResponse - 114, // 281: substrate.ateapi.v1.Control.MarkWorkerUnavailable:output_type -> substrate.ateapi.v1.MarkWorkerUnavailableResponse - 102, // 282: substrate.ateapi.v1.Control.ListWorkerActorAssignments:output_type -> substrate.ateapi.v1.ListWorkerActorAssignmentsResponse - 116, // 283: substrate.ateapi.v1.Control.ListActors:output_type -> substrate.ateapi.v1.ListActorsResponse - 34, // 284: substrate.ateapi.v1.Control.CreateAtespace:output_type -> substrate.ateapi.v1.Atespace - 34, // 285: substrate.ateapi.v1.Control.GetAtespace:output_type -> substrate.ateapi.v1.Atespace - 64, // 286: substrate.ateapi.v1.Control.ListAtespaces:output_type -> substrate.ateapi.v1.ListAtespacesResponse - 34, // 287: substrate.ateapi.v1.Control.DeleteAtespace:output_type -> substrate.ateapi.v1.Atespace - 54, // 288: substrate.ateapi.v1.Control.CreateExternalVolumeClass:output_type -> substrate.ateapi.v1.ExternalVolumeClass - 54, // 289: substrate.ateapi.v1.Control.GetExternalVolumeClass:output_type -> substrate.ateapi.v1.ExternalVolumeClass - 69, // 290: substrate.ateapi.v1.Control.ListExternalVolumeClasses:output_type -> substrate.ateapi.v1.ListExternalVolumeClassesResponse - 54, // 291: substrate.ateapi.v1.Control.DeleteExternalVolumeClass:output_type -> substrate.ateapi.v1.ExternalVolumeClass - 36, // 292: substrate.ateapi.v1.Control.CreateActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate - 36, // 293: substrate.ateapi.v1.Control.GetActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate - 74, // 294: substrate.ateapi.v1.Control.ListActorTemplates:output_type -> substrate.ateapi.v1.ListActorTemplatesResponse - 36, // 295: substrate.ateapi.v1.Control.DeleteActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate - 145, // 296: substrate.ateapi.v1.Control.GetGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 145, // 297: substrate.ateapi.v1.Control.CreateGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 145, // 298: substrate.ateapi.v1.Control.UpdateGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 145, // 299: substrate.ateapi.v1.Control.GetAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 145, // 300: substrate.ateapi.v1.Control.CreateAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 145, // 301: substrate.ateapi.v1.Control.UpdateAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 145, // 302: substrate.ateapi.v1.Control.DeleteAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 128, // 303: substrate.ateapi.v1.WorkerService.AcquireWorkerEpoch:output_type -> substrate.ateapi.v1.AcquireWorkerEpochResponse - 130, // 304: substrate.ateapi.v1.WorkerService.RegisterWorker:output_type -> substrate.ateapi.v1.RegisterWorkerResponse - 132, // 305: substrate.ateapi.v1.WorkerService.SetWorkerSandboxRuntimes:output_type -> substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse - 134, // 306: substrate.ateapi.v1.WorkerService.MintWorkerActorCertificate:output_type -> substrate.ateapi.v1.MintWorkerActorCertificateResponse - 136, // 307: substrate.ateapi.v1.WorkerService.MintWorkerActorJwt:output_type -> substrate.ateapi.v1.MintWorkerActorJwtResponse - 138, // 308: substrate.ateapi.v1.WorkerService.RequestActorSuspend:output_type -> substrate.ateapi.v1.RequestActorSuspendResponse - 142, // 309: substrate.ateapi.v1.WorkerService.ReportActorSnapshotState:output_type -> substrate.ateapi.v1.ReportActorSnapshotStateResponse - 140, // 310: substrate.ateapi.v1.WorkerService.ReportActorCrashed:output_type -> substrate.ateapi.v1.ReportActorCrashedResponse - 257, // [257:311] is the sub-list for method output_type - 203, // [203:257] is the sub-list for method input_type - 201, // [201:203] is the sub-list for extension type_name - 199, // [199:201] is the sub-list for extension extendee - 0, // [0:199] is the sub-list for field type_name + 35, // 72: substrate.ateapi.v1.ExternalVolumeTemplate.external_volume_class:type_name -> substrate.ateapi.v1.ObjectRef + 14, // 73: substrate.ateapi.v1.ExternalVolumeClass.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata + 158, // 74: substrate.ateapi.v1.ExternalVolumeClass.parameters:type_name -> substrate.ateapi.v1.ExternalVolumeClass.ParametersEntry + 56, // 75: substrate.ateapi.v1.SystemInfoVolumeSource.data_sources:type_name -> substrate.ateapi.v1.SystemInfoDataSource + 57, // 76: substrate.ateapi.v1.SystemInfoDataSource.actor_metadata:type_name -> substrate.ateapi.v1.ActorMetadataDataSource + 59, // 77: substrate.ateapi.v1.SystemInfoDataSource.trust_bundle:type_name -> substrate.ateapi.v1.TrustBundleDataSource + 58, // 78: substrate.ateapi.v1.ActorMetadataDataSource.items:type_name -> substrate.ateapi.v1.ActorMetadataItem + 6, // 79: substrate.ateapi.v1.ActorMetadataItem.field:type_name -> substrate.ateapi.v1.ActorMetadataField + 34, // 80: substrate.ateapi.v1.CreateAtespaceRequest.atespace:type_name -> substrate.ateapi.v1.Atespace + 35, // 81: substrate.ateapi.v1.GetAtespaceRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef + 100, // 82: substrate.ateapi.v1.ListAtespacesRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 34, // 83: substrate.ateapi.v1.ListAtespacesResponse.atespaces:type_name -> substrate.ateapi.v1.Atespace + 35, // 84: substrate.ateapi.v1.DeleteAtespaceRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef + 99, // 85: substrate.ateapi.v1.DeleteAtespaceRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 54, // 86: substrate.ateapi.v1.CreateExternalVolumeClassRequest.external_volume_class:type_name -> substrate.ateapi.v1.ExternalVolumeClass + 35, // 87: substrate.ateapi.v1.GetExternalVolumeClassRequest.external_volume_class:type_name -> substrate.ateapi.v1.ObjectRef + 100, // 88: substrate.ateapi.v1.ListExternalVolumeClassesRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 54, // 89: substrate.ateapi.v1.ListExternalVolumeClassesResponse.external_volume_classes:type_name -> substrate.ateapi.v1.ExternalVolumeClass + 35, // 90: substrate.ateapi.v1.DeleteExternalVolumeClassRequest.external_volume_class:type_name -> substrate.ateapi.v1.ObjectRef + 99, // 91: substrate.ateapi.v1.DeleteExternalVolumeClassRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 36, // 92: substrate.ateapi.v1.CreateActorTemplateRequest.actor_template:type_name -> substrate.ateapi.v1.ActorTemplate + 35, // 93: substrate.ateapi.v1.GetActorTemplateRequest.actor_template:type_name -> substrate.ateapi.v1.ObjectRef + 100, // 94: substrate.ateapi.v1.ListActorTemplatesRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 36, // 95: substrate.ateapi.v1.ListActorTemplatesResponse.actor_templates:type_name -> substrate.ateapi.v1.ActorTemplate + 35, // 96: substrate.ateapi.v1.DeleteActorTemplateRequest.actor_template:type_name -> substrate.ateapi.v1.ObjectRef + 99, // 97: substrate.ateapi.v1.DeleteActorTemplateRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 35, // 98: substrate.ateapi.v1.GetActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 17, // 99: substrate.ateapi.v1.CreateActorRequest.actor:type_name -> substrate.ateapi.v1.Actor + 17, // 100: substrate.ateapi.v1.UpdateActorRequest.actor:type_name -> substrate.ateapi.v1.Actor + 35, // 101: substrate.ateapi.v1.SuspendActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 81, // 102: substrate.ateapi.v1.SuspendActorRequest.options:type_name -> substrate.ateapi.v1.SuspendOptions + 17, // 103: substrate.ateapi.v1.SuspendActorResponse.actor:type_name -> substrate.ateapi.v1.Actor + 7, // 104: substrate.ateapi.v1.SuspendOptions.mode:type_name -> substrate.ateapi.v1.DurabilityMode + 35, // 105: substrate.ateapi.v1.ResumeActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 17, // 106: substrate.ateapi.v1.ResumeActorResponse.actor:type_name -> substrate.ateapi.v1.Actor + 35, // 107: substrate.ateapi.v1.RevertActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 17, // 108: substrate.ateapi.v1.RevertActorResponse.actor:type_name -> substrate.ateapi.v1.Actor + 35, // 109: substrate.ateapi.v1.DeleteActorRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 99, // 110: substrate.ateapi.v1.DeleteActorRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 35, // 111: substrate.ateapi.v1.GetActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 112: substrate.ateapi.v1.CreateActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 18, // 113: substrate.ateapi.v1.CreateActorEgressPolicyRequest.egress_policy:type_name -> substrate.ateapi.v1.EgressPolicy + 35, // 114: substrate.ateapi.v1.UpdateActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 18, // 115: substrate.ateapi.v1.UpdateActorEgressPolicyRequest.egress_policy:type_name -> substrate.ateapi.v1.EgressPolicy + 35, // 116: substrate.ateapi.v1.DeleteActorEgressPolicyRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 99, // 117: substrate.ateapi.v1.DeleteActorEgressPolicyRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 35, // 118: substrate.ateapi.v1.GetTagRequest.tag:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 119: substrate.ateapi.v1.MintActorJwtRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 160, // 120: substrate.ateapi.v1.MintActorJwtResponse.expire_time:type_name -> google.protobuf.Timestamp + 100, // 121: substrate.ateapi.v1.ListTagsRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 33, // 122: substrate.ateapi.v1.ListTagsResponse.tags:type_name -> substrate.ateapi.v1.Tag + 33, // 123: substrate.ateapi.v1.CreateTagRequest.tag:type_name -> substrate.ateapi.v1.Tag + 33, // 124: substrate.ateapi.v1.UpdateTagRequest.tag:type_name -> substrate.ateapi.v1.Tag + 35, // 125: substrate.ateapi.v1.DeleteTagRequest.tag:type_name -> substrate.ateapi.v1.ObjectRef + 99, // 126: substrate.ateapi.v1.DeleteTagRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 35, // 127: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 100, // 128: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 126, // 129: substrate.ateapi.v1.ListWorkerActorAssignmentsResponse.actor_assignments:type_name -> substrate.ateapi.v1.ActorAssignment + 100, // 130: substrate.ateapi.v1.ListWorkersRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 117, // 131: substrate.ateapi.v1.ListWorkersResponse.workers:type_name -> substrate.ateapi.v1.Worker + 35, // 132: substrate.ateapi.v1.GetWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 117, // 133: substrate.ateapi.v1.CreateWorkerRequest.worker:type_name -> substrate.ateapi.v1.Worker + 117, // 134: substrate.ateapi.v1.UpdateWorkerRequest.worker:type_name -> substrate.ateapi.v1.Worker + 35, // 135: substrate.ateapi.v1.DeleteWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 99, // 136: substrate.ateapi.v1.DeleteWorkerRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 35, // 137: substrate.ateapi.v1.DrainWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 117, // 138: substrate.ateapi.v1.DrainWorkerResponse.worker:type_name -> substrate.ateapi.v1.Worker + 35, // 139: substrate.ateapi.v1.MarkWorkerAvailableRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 117, // 140: substrate.ateapi.v1.MarkWorkerAvailableResponse.worker:type_name -> substrate.ateapi.v1.Worker + 35, // 141: substrate.ateapi.v1.MarkWorkerUnavailableRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 117, // 142: substrate.ateapi.v1.MarkWorkerUnavailableResponse.worker:type_name -> substrate.ateapi.v1.Worker + 100, // 143: substrate.ateapi.v1.ListActorsRequest.options:type_name -> substrate.ateapi.v1.ListOptions + 17, // 144: substrate.ateapi.v1.ListActorsResponse.actors:type_name -> substrate.ateapi.v1.Actor + 14, // 145: substrate.ateapi.v1.Worker.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata + 159, // 146: substrate.ateapi.v1.Worker.labels:type_name -> substrate.ateapi.v1.Worker.LabelsEntry + 118, // 147: substrate.ateapi.v1.Worker.status:type_name -> substrate.ateapi.v1.WorkerStatus + 8, // 148: substrate.ateapi.v1.WorkerStatus.state:type_name -> substrate.ateapi.v1.WorkerState + 125, // 149: substrate.ateapi.v1.WorkerStatus.capacity:type_name -> substrate.ateapi.v1.WorkerResources + 125, // 150: substrate.ateapi.v1.WorkerStatus.allocated:type_name -> substrate.ateapi.v1.WorkerResources + 119, // 151: substrate.ateapi.v1.WorkerStatus.sandbox_classes:type_name -> substrate.ateapi.v1.WorkerSandboxClass + 120, // 152: substrate.ateapi.v1.WorkerSandboxClass.default_runtime:type_name -> substrate.ateapi.v1.WorkerSandboxRuntime + 120, // 153: substrate.ateapi.v1.WorkerSandboxClass.restorable_runtimes:type_name -> substrate.ateapi.v1.WorkerSandboxRuntime + 123, // 154: substrate.ateapi.v1.WorkerSandboxRuntime.version:type_name -> substrate.ateapi.v1.VersionedSandboxCompat + 121, // 155: substrate.ateapi.v1.WorkerSandboxRuntime.actor_overhead:type_name -> substrate.ateapi.v1.RuntimeOverhead + 123, // 156: substrate.ateapi.v1.ActorSandboxRuntime.version:type_name -> substrate.ateapi.v1.VersionedSandboxCompat + 124, // 157: substrate.ateapi.v1.VersionedSandboxCompat.attributes:type_name -> substrate.ateapi.v1.AttributeEntry + 14, // 158: substrate.ateapi.v1.ActorAssignment.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata + 35, // 159: substrate.ateapi.v1.ActorAssignment.actor:type_name -> substrate.ateapi.v1.ObjectRef + 38, // 160: substrate.ateapi.v1.ActorAssignment.resources:type_name -> substrate.ateapi.v1.Resources + 35, // 161: substrate.ateapi.v1.AcquireWorkerEpochRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 162: substrate.ateapi.v1.RegisterWorkerRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 125, // 163: substrate.ateapi.v1.RegisterWorkerRequest.capacity:type_name -> substrate.ateapi.v1.WorkerResources + 117, // 164: substrate.ateapi.v1.RegisterWorkerResponse.worker:type_name -> substrate.ateapi.v1.Worker + 35, // 165: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 119, // 166: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest.sandbox_classes:type_name -> substrate.ateapi.v1.WorkerSandboxClass + 117, // 167: substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse.worker:type_name -> substrate.ateapi.v1.Worker + 35, // 168: substrate.ateapi.v1.MintWorkerActorCertificateRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 169: substrate.ateapi.v1.MintWorkerActorCertificateRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 170: substrate.ateapi.v1.MintWorkerActorJwtRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 160, // 171: substrate.ateapi.v1.MintWorkerActorJwtResponse.expire_time:type_name -> google.protobuf.Timestamp + 35, // 172: substrate.ateapi.v1.RequestActorSuspendRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 173: substrate.ateapi.v1.RequestActorSuspendRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 17, // 174: substrate.ateapi.v1.RequestActorSuspendResponse.actor:type_name -> substrate.ateapi.v1.Actor + 35, // 175: substrate.ateapi.v1.ReportActorCrashedRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 176: substrate.ateapi.v1.ReportActorCrashedRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 17, // 177: substrate.ateapi.v1.ReportActorCrashedResponse.actor:type_name -> substrate.ateapi.v1.Actor + 35, // 178: substrate.ateapi.v1.ReportActorSnapshotStateRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef + 143, // 179: substrate.ateapi.v1.ReportActorSnapshotStateRequest.state:type_name -> substrate.ateapi.v1.ActorSnapshotState + 144, // 180: substrate.ateapi.v1.ActorSnapshotState.latest_local:type_name -> substrate.ateapi.v1.SnapshotReport + 144, // 181: substrate.ateapi.v1.ActorSnapshotState.uploading:type_name -> substrate.ateapi.v1.SnapshotReport + 144, // 182: substrate.ateapi.v1.ActorSnapshotState.latest_durable:type_name -> substrate.ateapi.v1.SnapshotReport + 160, // 183: substrate.ateapi.v1.ActorSnapshotState.upload_due_time:type_name -> google.protobuf.Timestamp + 2, // 184: substrate.ateapi.v1.SnapshotReport.fidelity:type_name -> substrate.ateapi.v1.SnapshotFidelity + 10, // 185: substrate.ateapi.v1.SnapshotReport.object:type_name -> substrate.ateapi.v1.ObjectSnapshot + 160, // 186: substrate.ateapi.v1.SnapshotReport.local_commit_time:type_name -> google.protobuf.Timestamp + 160, // 187: substrate.ateapi.v1.SnapshotReport.durable_complete_time:type_name -> google.protobuf.Timestamp + 14, // 188: substrate.ateapi.v1.AccessPolicy.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata + 146, // 189: substrate.ateapi.v1.AccessPolicy.bindings:type_name -> substrate.ateapi.v1.Binding + 145, // 190: substrate.ateapi.v1.CreateGlobalAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy + 145, // 191: substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy + 35, // 192: substrate.ateapi.v1.GetAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 193: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef + 145, // 194: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy + 35, // 195: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef + 145, // 196: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy + 35, // 197: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef + 99, // 198: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 9, // 199: substrate.ateapi.v1.ResourceAnnotation.scope:type_name -> substrate.ateapi.v1.Scope + 161, // 200: substrate.ateapi.v1.resource:extendee -> google.protobuf.MessageOptions + 162, // 201: substrate.ateapi.v1.method:extendee -> google.protobuf.MethodOptions + 154, // 202: substrate.ateapi.v1.resource:type_name -> substrate.ateapi.v1.ResourceAnnotation + 155, // 203: substrate.ateapi.v1.method:type_name -> substrate.ateapi.v1.MethodAnnotation + 76, // 204: substrate.ateapi.v1.Control.GetActor:input_type -> substrate.ateapi.v1.GetActorRequest + 77, // 205: substrate.ateapi.v1.Control.CreateActor:input_type -> substrate.ateapi.v1.CreateActorRequest + 78, // 206: substrate.ateapi.v1.Control.UpdateActor:input_type -> substrate.ateapi.v1.UpdateActorRequest + 79, // 207: substrate.ateapi.v1.Control.SuspendActor:input_type -> substrate.ateapi.v1.SuspendActorRequest + 82, // 208: substrate.ateapi.v1.Control.ResumeActor:input_type -> substrate.ateapi.v1.ResumeActorRequest + 84, // 209: substrate.ateapi.v1.Control.RevertActor:input_type -> substrate.ateapi.v1.RevertActorRequest + 86, // 210: substrate.ateapi.v1.Control.DeleteActor:input_type -> substrate.ateapi.v1.DeleteActorRequest + 87, // 211: substrate.ateapi.v1.Control.GetActorEgressPolicy:input_type -> substrate.ateapi.v1.GetActorEgressPolicyRequest + 88, // 212: substrate.ateapi.v1.Control.CreateActorEgressPolicy:input_type -> substrate.ateapi.v1.CreateActorEgressPolicyRequest + 89, // 213: substrate.ateapi.v1.Control.UpdateActorEgressPolicy:input_type -> substrate.ateapi.v1.UpdateActorEgressPolicyRequest + 90, // 214: substrate.ateapi.v1.Control.DeleteActorEgressPolicy:input_type -> substrate.ateapi.v1.DeleteActorEgressPolicyRequest + 92, // 215: substrate.ateapi.v1.Control.MintActorJwt:input_type -> substrate.ateapi.v1.MintActorJwtRequest + 96, // 216: substrate.ateapi.v1.Control.CreateTag:input_type -> substrate.ateapi.v1.CreateTagRequest + 91, // 217: substrate.ateapi.v1.Control.GetTag:input_type -> substrate.ateapi.v1.GetTagRequest + 94, // 218: substrate.ateapi.v1.Control.ListTags:input_type -> substrate.ateapi.v1.ListTagsRequest + 97, // 219: substrate.ateapi.v1.Control.UpdateTag:input_type -> substrate.ateapi.v1.UpdateTagRequest + 98, // 220: substrate.ateapi.v1.Control.DeleteTag:input_type -> substrate.ateapi.v1.DeleteTagRequest + 103, // 221: substrate.ateapi.v1.Control.ListWorkers:input_type -> substrate.ateapi.v1.ListWorkersRequest + 105, // 222: substrate.ateapi.v1.Control.GetWorker:input_type -> substrate.ateapi.v1.GetWorkerRequest + 106, // 223: substrate.ateapi.v1.Control.CreateWorker:input_type -> substrate.ateapi.v1.CreateWorkerRequest + 107, // 224: substrate.ateapi.v1.Control.UpdateWorker:input_type -> substrate.ateapi.v1.UpdateWorkerRequest + 108, // 225: substrate.ateapi.v1.Control.DeleteWorker:input_type -> substrate.ateapi.v1.DeleteWorkerRequest + 109, // 226: substrate.ateapi.v1.Control.DrainWorker:input_type -> substrate.ateapi.v1.DrainWorkerRequest + 111, // 227: substrate.ateapi.v1.Control.MarkWorkerAvailable:input_type -> substrate.ateapi.v1.MarkWorkerAvailableRequest + 113, // 228: substrate.ateapi.v1.Control.MarkWorkerUnavailable:input_type -> substrate.ateapi.v1.MarkWorkerUnavailableRequest + 101, // 229: substrate.ateapi.v1.Control.ListWorkerActorAssignments:input_type -> substrate.ateapi.v1.ListWorkerActorAssignmentsRequest + 115, // 230: substrate.ateapi.v1.Control.ListActors:input_type -> substrate.ateapi.v1.ListActorsRequest + 61, // 231: substrate.ateapi.v1.Control.CreateAtespace:input_type -> substrate.ateapi.v1.CreateAtespaceRequest + 62, // 232: substrate.ateapi.v1.Control.GetAtespace:input_type -> substrate.ateapi.v1.GetAtespaceRequest + 63, // 233: substrate.ateapi.v1.Control.ListAtespaces:input_type -> substrate.ateapi.v1.ListAtespacesRequest + 65, // 234: substrate.ateapi.v1.Control.DeleteAtespace:input_type -> substrate.ateapi.v1.DeleteAtespaceRequest + 66, // 235: substrate.ateapi.v1.Control.CreateExternalVolumeClass:input_type -> substrate.ateapi.v1.CreateExternalVolumeClassRequest + 67, // 236: substrate.ateapi.v1.Control.GetExternalVolumeClass:input_type -> substrate.ateapi.v1.GetExternalVolumeClassRequest + 68, // 237: substrate.ateapi.v1.Control.ListExternalVolumeClasses:input_type -> substrate.ateapi.v1.ListExternalVolumeClassesRequest + 70, // 238: substrate.ateapi.v1.Control.DeleteExternalVolumeClass:input_type -> substrate.ateapi.v1.DeleteExternalVolumeClassRequest + 71, // 239: substrate.ateapi.v1.Control.CreateActorTemplate:input_type -> substrate.ateapi.v1.CreateActorTemplateRequest + 72, // 240: substrate.ateapi.v1.Control.GetActorTemplate:input_type -> substrate.ateapi.v1.GetActorTemplateRequest + 73, // 241: substrate.ateapi.v1.Control.ListActorTemplates:input_type -> substrate.ateapi.v1.ListActorTemplatesRequest + 75, // 242: substrate.ateapi.v1.Control.DeleteActorTemplate:input_type -> substrate.ateapi.v1.DeleteActorTemplateRequest + 147, // 243: substrate.ateapi.v1.Control.GetGlobalAccessPolicy:input_type -> substrate.ateapi.v1.GetGlobalAccessPolicyRequest + 148, // 244: substrate.ateapi.v1.Control.CreateGlobalAccessPolicy:input_type -> substrate.ateapi.v1.CreateGlobalAccessPolicyRequest + 149, // 245: substrate.ateapi.v1.Control.UpdateGlobalAccessPolicy:input_type -> substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest + 150, // 246: substrate.ateapi.v1.Control.GetAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.GetAtespaceAccessPolicyRequest + 151, // 247: substrate.ateapi.v1.Control.CreateAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest + 152, // 248: substrate.ateapi.v1.Control.UpdateAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest + 153, // 249: substrate.ateapi.v1.Control.DeleteAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest + 127, // 250: substrate.ateapi.v1.WorkerService.AcquireWorkerEpoch:input_type -> substrate.ateapi.v1.AcquireWorkerEpochRequest + 129, // 251: substrate.ateapi.v1.WorkerService.RegisterWorker:input_type -> substrate.ateapi.v1.RegisterWorkerRequest + 131, // 252: substrate.ateapi.v1.WorkerService.SetWorkerSandboxRuntimes:input_type -> substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest + 133, // 253: substrate.ateapi.v1.WorkerService.MintWorkerActorCertificate:input_type -> substrate.ateapi.v1.MintWorkerActorCertificateRequest + 135, // 254: substrate.ateapi.v1.WorkerService.MintWorkerActorJwt:input_type -> substrate.ateapi.v1.MintWorkerActorJwtRequest + 137, // 255: substrate.ateapi.v1.WorkerService.RequestActorSuspend:input_type -> substrate.ateapi.v1.RequestActorSuspendRequest + 141, // 256: substrate.ateapi.v1.WorkerService.ReportActorSnapshotState:input_type -> substrate.ateapi.v1.ReportActorSnapshotStateRequest + 139, // 257: substrate.ateapi.v1.WorkerService.ReportActorCrashed:input_type -> substrate.ateapi.v1.ReportActorCrashedRequest + 17, // 258: substrate.ateapi.v1.Control.GetActor:output_type -> substrate.ateapi.v1.Actor + 17, // 259: substrate.ateapi.v1.Control.CreateActor:output_type -> substrate.ateapi.v1.Actor + 17, // 260: substrate.ateapi.v1.Control.UpdateActor:output_type -> substrate.ateapi.v1.Actor + 80, // 261: substrate.ateapi.v1.Control.SuspendActor:output_type -> substrate.ateapi.v1.SuspendActorResponse + 83, // 262: substrate.ateapi.v1.Control.ResumeActor:output_type -> substrate.ateapi.v1.ResumeActorResponse + 85, // 263: substrate.ateapi.v1.Control.RevertActor:output_type -> substrate.ateapi.v1.RevertActorResponse + 17, // 264: substrate.ateapi.v1.Control.DeleteActor:output_type -> substrate.ateapi.v1.Actor + 18, // 265: substrate.ateapi.v1.Control.GetActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy + 18, // 266: substrate.ateapi.v1.Control.CreateActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy + 18, // 267: substrate.ateapi.v1.Control.UpdateActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy + 18, // 268: substrate.ateapi.v1.Control.DeleteActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy + 93, // 269: substrate.ateapi.v1.Control.MintActorJwt:output_type -> substrate.ateapi.v1.MintActorJwtResponse + 33, // 270: substrate.ateapi.v1.Control.CreateTag:output_type -> substrate.ateapi.v1.Tag + 33, // 271: substrate.ateapi.v1.Control.GetTag:output_type -> substrate.ateapi.v1.Tag + 95, // 272: substrate.ateapi.v1.Control.ListTags:output_type -> substrate.ateapi.v1.ListTagsResponse + 33, // 273: substrate.ateapi.v1.Control.UpdateTag:output_type -> substrate.ateapi.v1.Tag + 33, // 274: substrate.ateapi.v1.Control.DeleteTag:output_type -> substrate.ateapi.v1.Tag + 104, // 275: substrate.ateapi.v1.Control.ListWorkers:output_type -> substrate.ateapi.v1.ListWorkersResponse + 117, // 276: substrate.ateapi.v1.Control.GetWorker:output_type -> substrate.ateapi.v1.Worker + 117, // 277: substrate.ateapi.v1.Control.CreateWorker:output_type -> substrate.ateapi.v1.Worker + 117, // 278: substrate.ateapi.v1.Control.UpdateWorker:output_type -> substrate.ateapi.v1.Worker + 117, // 279: substrate.ateapi.v1.Control.DeleteWorker:output_type -> substrate.ateapi.v1.Worker + 110, // 280: substrate.ateapi.v1.Control.DrainWorker:output_type -> substrate.ateapi.v1.DrainWorkerResponse + 112, // 281: substrate.ateapi.v1.Control.MarkWorkerAvailable:output_type -> substrate.ateapi.v1.MarkWorkerAvailableResponse + 114, // 282: substrate.ateapi.v1.Control.MarkWorkerUnavailable:output_type -> substrate.ateapi.v1.MarkWorkerUnavailableResponse + 102, // 283: substrate.ateapi.v1.Control.ListWorkerActorAssignments:output_type -> substrate.ateapi.v1.ListWorkerActorAssignmentsResponse + 116, // 284: substrate.ateapi.v1.Control.ListActors:output_type -> substrate.ateapi.v1.ListActorsResponse + 34, // 285: substrate.ateapi.v1.Control.CreateAtespace:output_type -> substrate.ateapi.v1.Atespace + 34, // 286: substrate.ateapi.v1.Control.GetAtespace:output_type -> substrate.ateapi.v1.Atespace + 64, // 287: substrate.ateapi.v1.Control.ListAtespaces:output_type -> substrate.ateapi.v1.ListAtespacesResponse + 34, // 288: substrate.ateapi.v1.Control.DeleteAtespace:output_type -> substrate.ateapi.v1.Atespace + 54, // 289: substrate.ateapi.v1.Control.CreateExternalVolumeClass:output_type -> substrate.ateapi.v1.ExternalVolumeClass + 54, // 290: substrate.ateapi.v1.Control.GetExternalVolumeClass:output_type -> substrate.ateapi.v1.ExternalVolumeClass + 69, // 291: substrate.ateapi.v1.Control.ListExternalVolumeClasses:output_type -> substrate.ateapi.v1.ListExternalVolumeClassesResponse + 54, // 292: substrate.ateapi.v1.Control.DeleteExternalVolumeClass:output_type -> substrate.ateapi.v1.ExternalVolumeClass + 36, // 293: substrate.ateapi.v1.Control.CreateActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate + 36, // 294: substrate.ateapi.v1.Control.GetActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate + 74, // 295: substrate.ateapi.v1.Control.ListActorTemplates:output_type -> substrate.ateapi.v1.ListActorTemplatesResponse + 36, // 296: substrate.ateapi.v1.Control.DeleteActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate + 145, // 297: substrate.ateapi.v1.Control.GetGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 145, // 298: substrate.ateapi.v1.Control.CreateGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 145, // 299: substrate.ateapi.v1.Control.UpdateGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 145, // 300: substrate.ateapi.v1.Control.GetAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 145, // 301: substrate.ateapi.v1.Control.CreateAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 145, // 302: substrate.ateapi.v1.Control.UpdateAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 145, // 303: substrate.ateapi.v1.Control.DeleteAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 128, // 304: substrate.ateapi.v1.WorkerService.AcquireWorkerEpoch:output_type -> substrate.ateapi.v1.AcquireWorkerEpochResponse + 130, // 305: substrate.ateapi.v1.WorkerService.RegisterWorker:output_type -> substrate.ateapi.v1.RegisterWorkerResponse + 132, // 306: substrate.ateapi.v1.WorkerService.SetWorkerSandboxRuntimes:output_type -> substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse + 134, // 307: substrate.ateapi.v1.WorkerService.MintWorkerActorCertificate:output_type -> substrate.ateapi.v1.MintWorkerActorCertificateResponse + 136, // 308: substrate.ateapi.v1.WorkerService.MintWorkerActorJwt:output_type -> substrate.ateapi.v1.MintWorkerActorJwtResponse + 138, // 309: substrate.ateapi.v1.WorkerService.RequestActorSuspend:output_type -> substrate.ateapi.v1.RequestActorSuspendResponse + 142, // 310: substrate.ateapi.v1.WorkerService.ReportActorSnapshotState:output_type -> substrate.ateapi.v1.ReportActorSnapshotStateResponse + 140, // 311: substrate.ateapi.v1.WorkerService.ReportActorCrashed:output_type -> substrate.ateapi.v1.ReportActorCrashedResponse + 258, // [258:312] is the sub-list for method output_type + 204, // [204:258] is the sub-list for method input_type + 202, // [202:204] is the sub-list for extension type_name + 200, // [200:202] is the sub-list for extension extendee + 0, // [0:200] is the sub-list for field type_name } func init() { file_api_ateapi_v1_ateapi_proto_init() } diff --git a/api/ateapi/v1/ateapi.proto b/api/ateapi/v1/ateapi.proto index 89977164d2..7a1675d07f 100644 --- a/api/ateapi/v1/ateapi.proto +++ b/api/ateapi/v1/ateapi.proto @@ -1576,11 +1576,22 @@ message ExternalVolumeTemplate { int64 capacity_bytes = 1; // storage_class_name names the cluster-scoped Kubernetes StorageClass to - // create the volume from. Required. + // create the volume from. Prefer external_volume_class. // - // +k8s:required + // Exactly one of storage_class_name and external_volume_class must be set. + // + // +k8s:optional + // +k8s:unionMember // +k8s:format=k8s-long-name string storage_class_name = 2; + + // external_volume_class names the ExternalVolumeClass to create the volume + // from. atespace must be empty. + // + // +k8s:optional + // +k8s:unionMember + // +k8s:beta(since: "0.0")=+k8s:subfield(atespace)=+k8s:forbidden # TODO: get rid of beta prefix + ObjectRef external_volume_class = 3; } // ExternalVolumeClass names the CSI driver that provisions external volumes diff --git a/cmd/ateapi/internal/apivalidation/actor_template_test.go b/cmd/ateapi/internal/apivalidation/actor_template_test.go index 0c32ef3440..4fc47e1c66 100644 --- a/cmd/ateapi/internal/apivalidation/actor_template_test.go +++ b/cmd/ateapi/internal/apivalidation/actor_template_test.go @@ -932,12 +932,40 @@ func TestValidateActorTemplate(t *testing.T) { want: field.ErrorList{field.Forbidden(field.NewPath("volumes").Index(0).Child("external"), "")}, wantWithPreview: map[string]field.ErrorList{"ALL": {field.Invalid(field.NewPath("volumes").Index(0).Child("external", "template", "capacity_bytes"), nil, "").WithOrigin("minimum")}}, }, { - name: "external volume template missing storage_class_name", + name: "external volume template with no class", mutate: func(tmpl *ateapi.ActorTemplate) { tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: 10 << 30}}}} }, want: field.ErrorList{field.Forbidden(field.NewPath("volumes").Index(0).Child("external"), "")}, - wantWithPreview: map[string]field.ErrorList{"ALL": {field.Required(field.NewPath("volumes").Index(0).Child("external", "template", "storage_class_name"), "")}}, + wantWithPreview: map[string]field.ErrorList{"ALL": {field.Invalid(field.NewPath("volumes").Index(0).Child("external", "template"), nil, "one of").WithOrigin("union")}}, + }, { + name: "valid external volume template with external_volume_class", + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: 10 << 30, ExternalVolumeClass: &ateapi.ObjectRef{Name: "fast-ssd"}}}}} + }, + want: field.ErrorList{field.Forbidden(field.NewPath("volumes").Index(0).Child("external"), "")}, + wantWithPreview: map[string]field.ErrorList{"ALL": nil}, + }, { + name: "external volume template with both storage_class_name and external_volume_class", + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: 10 << 30, StorageClassName: "fast-ssd", ExternalVolumeClass: &ateapi.ObjectRef{Name: "fast-ssd"}}}}} + }, + want: field.ErrorList{field.Forbidden(field.NewPath("volumes").Index(0).Child("external"), "")}, + wantWithPreview: map[string]field.ErrorList{"ALL": {field.Invalid(field.NewPath("volumes").Index(0).Child("external", "template"), nil, "one of").WithOrigin("union")}}, + }, { + name: "external_volume_class with an atespace", + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: 10 << 30, ExternalVolumeClass: &ateapi.ObjectRef{Atespace: "ns1", Name: "fast-ssd"}}}}} + }, + want: field.ErrorList{field.Forbidden(field.NewPath("volumes").Index(0).Child("external"), "")}, + wantWithPreview: map[string]field.ErrorList{"ALL": {field.Forbidden(field.NewPath("volumes").Index(0).Child("external", "template", "external_volume_class", "atespace"), "")}}, + }, { + name: "external_volume_class missing name", + mutate: func(tmpl *ateapi.ActorTemplate) { + tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: 10 << 30, ExternalVolumeClass: &ateapi.ObjectRef{}}}}} + }, + want: field.ErrorList{field.Forbidden(field.NewPath("volumes").Index(0).Child("external"), "")}, + wantWithPreview: map[string]field.ErrorList{"ALL": {field.Required(field.NewPath("volumes").Index(0).Child("external", "template", "external_volume_class", "name"), "")}}, }, { name: "external volume template invalid storage_class_name", mutate: func(tmpl *ateapi.ActorTemplate) { diff --git a/cmd/ateapi/internal/apivalidation/zz_generated.validation.go b/cmd/ateapi/internal/apivalidation/zz_generated.validation.go index edaf622c2c..1f42e7e26a 100644 --- a/cmd/ateapi/internal/apivalidation/zz_generated.validation.go +++ b/cmd/ateapi/internal/apivalidation/zz_generated.validation.go @@ -4387,12 +4387,31 @@ func Validate_ExternalVolumeStatus( return errs } +var unionMembershipFor_go_ate_dev_substrate_api_ateapi_v1_ExternalVolumeTemplate_ = validate.NewUnionMembership(validate.NewUnionMember("storage_class_name"), validate.NewUnionMember("external_volume_class")) + // Validate_ExternalVolumeTemplate validates an instance of ExternalVolumeTemplate according // to declarative validation rules in the API schema. func Validate_ExternalVolumeTemplate( ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *v1.ExternalVolumeTemplate) (errs field.ErrorList) { + if e := validate.Union(ctx, op, fldPath, obj, oldObj, unionMembershipFor_go_ate_dev_substrate_api_ateapi_v1_ExternalVolumeTemplate_, + func(obj *v1.ExternalVolumeTemplate) bool { + if obj == nil { + return false + } + var z string + return obj.StorageClassName != z + }, + func(obj *v1.ExternalVolumeTemplate) bool { + if obj == nil { + return false + } + return obj.ExternalVolumeClass != nil + }); len(e) != 0 { + errs = append(errs, e...) + } + { // field v1.ExternalVolumeTemplate.CapacityBytes fn := func( fldPath *field.Path, @@ -4438,8 +4457,7 @@ func Validate_ExternalVolumeTemplate( } // 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 { @@ -4457,6 +4475,55 @@ func Validate_ExternalVolumeTemplate( errs = append(errs, fn(fldPath.Child("storage_class_name"), &obj.StorageClassName, oldVal, oldObj != nil)...) } + { // field v1.ExternalVolumeTemplate.ExternalVolumeClass + fn := func( + fldPath *field.Path, + obj, oldObj *v1.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.OptionalPointer(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + 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 *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().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 *v1.ExternalVolumeTemplate) *v1.ObjectRef { + return oldObj.ExternalVolumeClass + }) + errs = append(errs, fn(fldPath.Child("external_volume_class"), obj.ExternalVolumeClass, oldVal, oldObj != nil)...) + } + return errs } From 09b558372cf1cdbd9035ed329d45da3f985c1086 Mon Sep 17 00:00:00 2001 From: Vu Le Date: Tue, 10 Nov 2026 00:35:25 +0000 Subject: [PATCH 11/30] volume resolver, provisioning wiring, and unit+functional tests Signed-off-by: Vu Le --- .../apivalidation/actor_template_test.go | 5 + cmd/ateapi/internal/controlapi/actor.go | 2 +- .../controlapi/functionaltest/actor_test.go | 143 ++++++++++++++++ cmd/ateapi/internal/controlapi/volumes.go | 90 +++++++--- .../internal/controlapi/volumes_test.go | 160 +++++++++++++++++- cmd/ateapi/internal/controlapi/workflow.go | 1 + .../internal/controlapi/workflow_resume.go | 2 +- internal/volume/plugin.go | 2 +- 8 files changed, 376 insertions(+), 29 deletions(-) diff --git a/cmd/ateapi/internal/apivalidation/actor_template_test.go b/cmd/ateapi/internal/apivalidation/actor_template_test.go index 4fc47e1c66..7dc0f80efe 100644 --- a/cmd/ateapi/internal/apivalidation/actor_template_test.go +++ b/cmd/ateapi/internal/apivalidation/actor_template_test.go @@ -935,6 +935,7 @@ func TestValidateActorTemplate(t *testing.T) { name: "external volume template with no class", mutate: func(tmpl *ateapi.ActorTemplate) { tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: 10 << 30}}}} + tmpl.Containers[0].VolumeMounts = []*ateapi.VolumeMount{{Name: "data", MountPath: "/var/data"}} }, want: field.ErrorList{field.Forbidden(field.NewPath("volumes").Index(0).Child("external"), "")}, wantWithPreview: map[string]field.ErrorList{"ALL": {field.Invalid(field.NewPath("volumes").Index(0).Child("external", "template"), nil, "one of").WithOrigin("union")}}, @@ -942,6 +943,7 @@ func TestValidateActorTemplate(t *testing.T) { name: "valid external volume template with external_volume_class", mutate: func(tmpl *ateapi.ActorTemplate) { tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: 10 << 30, ExternalVolumeClass: &ateapi.ObjectRef{Name: "fast-ssd"}}}}} + tmpl.Containers[0].VolumeMounts = []*ateapi.VolumeMount{{Name: "data", MountPath: "/var/data"}} }, want: field.ErrorList{field.Forbidden(field.NewPath("volumes").Index(0).Child("external"), "")}, wantWithPreview: map[string]field.ErrorList{"ALL": nil}, @@ -949,6 +951,7 @@ func TestValidateActorTemplate(t *testing.T) { name: "external volume template with both storage_class_name and external_volume_class", mutate: func(tmpl *ateapi.ActorTemplate) { tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: 10 << 30, StorageClassName: "fast-ssd", ExternalVolumeClass: &ateapi.ObjectRef{Name: "fast-ssd"}}}}} + tmpl.Containers[0].VolumeMounts = []*ateapi.VolumeMount{{Name: "data", MountPath: "/var/data"}} }, want: field.ErrorList{field.Forbidden(field.NewPath("volumes").Index(0).Child("external"), "")}, wantWithPreview: map[string]field.ErrorList{"ALL": {field.Invalid(field.NewPath("volumes").Index(0).Child("external", "template"), nil, "one of").WithOrigin("union")}}, @@ -956,6 +959,7 @@ func TestValidateActorTemplate(t *testing.T) { name: "external_volume_class with an atespace", mutate: func(tmpl *ateapi.ActorTemplate) { tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: 10 << 30, ExternalVolumeClass: &ateapi.ObjectRef{Atespace: "ns1", Name: "fast-ssd"}}}}} + tmpl.Containers[0].VolumeMounts = []*ateapi.VolumeMount{{Name: "data", MountPath: "/var/data"}} }, want: field.ErrorList{field.Forbidden(field.NewPath("volumes").Index(0).Child("external"), "")}, wantWithPreview: map[string]field.ErrorList{"ALL": {field.Forbidden(field.NewPath("volumes").Index(0).Child("external", "template", "external_volume_class", "atespace"), "")}}, @@ -963,6 +967,7 @@ func TestValidateActorTemplate(t *testing.T) { name: "external_volume_class missing name", mutate: func(tmpl *ateapi.ActorTemplate) { tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: 10 << 30, ExternalVolumeClass: &ateapi.ObjectRef{}}}}} + tmpl.Containers[0].VolumeMounts = []*ateapi.VolumeMount{{Name: "data", MountPath: "/var/data"}} }, want: field.ErrorList{field.Forbidden(field.NewPath("volumes").Index(0).Child("external"), "")}, wantWithPreview: map[string]field.ErrorList{"ALL": {field.Required(field.NewPath("volumes").Index(0).Child("external", "template", "external_volume_class", "name"), "")}}, diff --git a/cmd/ateapi/internal/controlapi/actor.go b/cmd/ateapi/internal/controlapi/actor.go index 9b690a9f12..d9f6c557a1 100644 --- a/cmd/ateapi/internal/controlapi/actor.go +++ b/cmd/ateapi/internal/controlapi/actor.go @@ -109,7 +109,7 @@ func (s *ServiceImpl) CreateActor(ctx context.Context, inActor *ateapi.Actor) (* // Volume creation is completed asynchronously after the actor is recorded. var initVols []*ateapi.ExternalVolumeStatus - if iv, err := initialExternalVolumes(ctx, s.storageClassLister, template); err != nil { + if iv, err := initialExternalVolumes(ctx, s, s.storageClassLister, template); err != nil { return nil, err } else if preview.IsEnabledFor(ctx, preview.GateExternalVolumes) { initVols = iv diff --git a/cmd/ateapi/internal/controlapi/functionaltest/actor_test.go b/cmd/ateapi/internal/controlapi/functionaltest/actor_test.go index 2d685e0e5e..678063aa9d 100644 --- a/cmd/ateapi/internal/controlapi/functionaltest/actor_test.go +++ b/cmd/ateapi/internal/controlapi/functionaltest/actor_test.go @@ -1992,6 +1992,149 @@ func TestActorLifecycle_WithExternalVolumes(t *testing.T) { } } +// TestActorLifecycle_WithExternalVolumeClass provisions a volume from an +// ExternalVolumeClass: the class's driver becomes the volume type, and its +// parameters reach the driver's CreateVolume call. +func TestActorLifecycle_WithExternalVolumeClass(t *testing.T) { + preview.InitForTest(t, "ExternalVolumes") + + ns := namespaceForTest("ns-lifecycle-evc") + tc := setupPreviewTest(t, ns) + defer tc.cleanup() + ctx := context.Background() + + class, err := tc.client.CreateExternalVolumeClass(ctx, &ateapi.CreateExternalVolumeClassRequest{ + ExternalVolumeClass: &ateapi.ExternalVolumeClass{ + Metadata: &ateapi.ResourceMetadata{Name: "evc-gold"}, + DriverName: "substrate.io/mock", + Parameters: map[string]string{"tier": "gold"}, + }, + }) + if err != nil { + t.Fatalf("CreateExternalVolumeClass failed: %v", err) + } + if class.GetDriverName() != "substrate.io/mock" { + t.Fatalf("driver = %q, want substrate.io/mock", class.GetDriverName()) + } + volumes := []*ateapi.Volume{{ + Name: "data-vol", + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ + ExternalVolumeClass: &ateapi.ObjectRef{Name: "evc-gold"}, + CapacityBytes: 20 << 30, + }}, + }} + mounts := []*ateapi.VolumeMount{{Name: "data-vol", MountPath: "/mnt/data"}} + createTemplateWithVolumes(t, tc, ns, volumes, mounts) + createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") + + actorRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: "actor-evc"} + createResp, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "actor-evc"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + }, + }) + if err != nil { + t.Fatalf("CreateActor failed: %v", err) + } + created := createResp.GetStatus().GetExternalVolumes().GetVolumes() + if len(created) != 1 || created[0].GetVolumeType() != "substrate.io/mock" || created[0].GetStorageVolumeId() != "" { + t.Fatalf("CreateActor volumes = %v, want 1 unprovisioned volume of type substrate.io/mock", created) + } + + resumeResp, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}) + if err != nil { + t.Fatalf("ResumeActor failed: %v", err) + } + resumed := resumeResp.GetActor().GetStatus().GetExternalVolumes().GetVolumes() + if len(resumed) != 1 || resumed[0].GetStorageVolumeId() == "" { + t.Fatalf("ResumeActor volumes = %v, want 1 provisioned volume", resumed) + } + if got := resumed[0].GetVolumeContext()["tier"]; got != "gold" { + t.Errorf("volume context tier = %q, want %q from the class parameters", got, "gold") + } + + if _, err := tc.client.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: actorRef}); err != nil { + t.Fatalf("DeleteActor failed: %v", err) + } +} + +// TestCreateActor_MissingExternalVolumeClass checks that CreateActor fails when +// the template names an ExternalVolumeClass that does not exist. +func TestCreateActor_MissingExternalVolumeClass(t *testing.T) { + preview.InitForTest(t, "ExternalVolumes") + + ns := namespaceForTest("ns-missing-evc") + tc := setupPreviewTest(t, ns) + defer tc.cleanup() + + volumes := []*ateapi.Volume{{ + Name: "data-vol", + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ + ExternalVolumeClass: &ateapi.ObjectRef{Name: "evc-missing"}, + CapacityBytes: 1 << 30, + }}, + }} + mounts := []*ateapi.VolumeMount{{Name: "data-vol", MountPath: "/mnt/data"}} + createTemplateWithVolumes(t, tc, ns, volumes, mounts) + + _, err := tc.client.CreateActor(context.Background(), &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "actor-missing-evc"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + }, + }) + assertGrpcErrorRegex(t, err, codes.FailedPrecondition, `ExternalVolumeClass "evc-missing" not found`) +} + +// TestResumeActor_DeletedExternalVolumeClass checks that a resume fails with +// FailedPrecondition, before any volume is created, when the template's +// ExternalVolumeClass was deleted after the actor was created. +func TestResumeActor_DeletedExternalVolumeClass(t *testing.T) { + preview.InitForTest(t, "ExternalVolumes") + + ns := namespaceForTest("ns-deleted-evc") + tc := setupPreviewTest(t, ns) + defer tc.cleanup() + ctx := context.Background() + + if _, err := tc.client.CreateExternalVolumeClass(ctx, &ateapi.CreateExternalVolumeClassRequest{ + ExternalVolumeClass: &ateapi.ExternalVolumeClass{ + Metadata: &ateapi.ResourceMetadata{Name: "evc-gone"}, + DriverName: "substrate.io/mock", + }, + }); err != nil { + t.Fatalf("CreateExternalVolumeClass failed: %v", err) + } + volumes := []*ateapi.Volume{{ + Name: "data-vol", + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ + ExternalVolumeClass: &ateapi.ObjectRef{Name: "evc-gone"}, + CapacityBytes: 1 << 30, + }}, + }} + mounts := []*ateapi.VolumeMount{{Name: "data-vol", MountPath: "/mnt/data"}} + createTemplateWithVolumes(t, tc, ns, volumes, mounts) + + actorRef := &ateapi.ObjectRef{Atespace: testAtespace, Name: "actor-deleted-evc"} + if _, err := tc.client.CreateActor(ctx, &ateapi.CreateActorRequest{ + Actor: &ateapi.Actor{ + Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "actor-deleted-evc"}, + ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl1"}, + }, + }); err != nil { + t.Fatalf("CreateActor failed: %v", err) + } + if _, err := tc.client.DeleteExternalVolumeClass(ctx, &ateapi.DeleteExternalVolumeClassRequest{ + ExternalVolumeClass: &ateapi.ObjectRef{Name: "evc-gone"}, + }); err != nil { + t.Fatalf("DeleteExternalVolumeClass failed: %v", err) + } + + _, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}) + assertGrpcErrorRegex(t, err, codes.FailedPrecondition, `ExternalVolumeClass "evc-gone" not found`) +} + type partialFailVolumePlugin struct { volume.VolumePluginControlPlane deleted []string diff --git a/cmd/ateapi/internal/controlapi/volumes.go b/cmd/ateapi/internal/controlapi/volumes.go index d9de1a3ff7..d89424743c 100644 --- a/cmd/ateapi/internal/controlapi/volumes.go +++ b/cmd/ateapi/internal/controlapi/volumes.go @@ -38,27 +38,79 @@ func externalVolumesStatus(vols []*ateapi.ExternalVolumeStatus) *ateapi.External return &ateapi.ExternalVolumes{Volumes: vols} } +// externalVolumeClassGetter reads an ExternalVolumeClass by name. ServiceImpl +// implements it and reports a missing class as a NotFound API error. +type externalVolumeClassGetter interface { + GetExternalVolumeClass(ctx context.Context, name string) (*ateapi.ExternalVolumeClass, error) +} + +// volumeClass is what an external volume template resolves to: the CSI driver, +// the parameters for its CreateVolume call, and a label that names the class +// in errors. +type volumeClass struct { + driver string + params map[string]string + label string +} + +// resolveVolumeClass resolves the class of an external volume template from +// external_volume_class when it is set, otherwise from the Kubernetes +// StorageClass named by storage_class_name. +func resolveVolumeClass(ctx context.Context, classes externalVolumeClassGetter, scLister storagev1listers.StorageClassLister, tmpl *ateapi.ExternalVolumeTemplate) (volumeClass, error) { + if ref := tmpl.GetExternalVolumeClass(); ref != nil { + driver, params, err := resolveExternalVolumeClass(ctx, classes, ref) + if err != nil { + return volumeClass{}, err + } + return volumeClass{driver: driver, params: params, label: fmt.Sprintf("ExternalVolumeClass %q", ref.GetName())}, nil + } + + scName := tmpl.GetStorageClassName() + if scName == "" { + return volumeClass{}, apierror.FailedPrecondition("external volume template sets neither external_volume_class nor storage_class_name") + } + sc, err := scLister.Get(scName) + if err != nil { + if k8serrors.IsNotFound(err) { + return volumeClass{}, apierror.FailedPrecondition("StorageClass %q not found", scName) + } + return volumeClass{}, apierror.Internal("failed to get StorageClass %q: %v", scName, err) + } + return volumeClass{driver: sc.Provisioner, params: sc.Parameters, label: fmt.Sprintf("StorageClass %q", scName)}, nil +} + +// resolveExternalVolumeClass returns the driver and CreateVolume parameters of +// the ExternalVolumeClass that ref names. A missing class is a +// FailedPrecondition: the template is valid, but the class it names does not +// exist yet or was deleted. +func resolveExternalVolumeClass(ctx context.Context, classes externalVolumeClassGetter, ref *ateapi.ObjectRef) (driver string, params map[string]string, err error) { + class, err := classes.GetExternalVolumeClass(ctx, ref.GetName()) + if err != nil { + if apierror.Code(err) == codes.NotFound { + return "", nil, apierror.FailedPrecondition("ExternalVolumeClass %q not found", ref.GetName()) + } + return "", nil, apierror.Internal("failed to get ExternalVolumeClass %q: %v", ref.GetName(), err) + } + return class.GetDriverName(), class.GetParameters(), nil +} + // initialExternalVolumes constructs the actor's volume objects before volume // creation. A volume has no storage volume ID until it is provisioned. -func initialExternalVolumes(ctx context.Context, scLister storagev1listers.StorageClassLister, template *ateapi.ActorTemplate) ([]*ateapi.ExternalVolumeStatus, error) { +func initialExternalVolumes(ctx context.Context, classes externalVolumeClassGetter, scLister storagev1listers.StorageClassLister, template *ateapi.ActorTemplate) ([]*ateapi.ExternalVolumeStatus, error) { if template == nil { return nil, apierror.InvalidArgument("template is required") } var volumes []*ateapi.ExternalVolumeStatus for _, vol := range template.GetVolumes() { - if vol.GetExternal().GetTemplate() != nil { - scName := vol.GetExternal().GetTemplate().GetStorageClassName() - sc, err := scLister.Get(scName) + if ext := vol.GetExternal().GetTemplate(); ext != nil { + class, err := resolveVolumeClass(ctx, classes, scLister, ext) if err != nil { - if k8serrors.IsNotFound(err) { - return nil, apierror.FailedPrecondition("StorageClass %q not found", scName) - } - return nil, apierror.Internal("failed to get StorageClass %q: %v", scName, err) + return nil, err } volumes = append(volumes, &ateapi.ExternalVolumeStatus{ Name: vol.GetName(), - VolumeType: sc.Provisioner, + VolumeType: class.driver, }) } } @@ -68,7 +120,7 @@ func initialExternalVolumes(ctx context.Context, scLister storagev1listers.Stora // createActorVolumes provisions the external volumes in volumesToCreate that have no storage volume ID, using the provided volume plugin. // It returns the list of external volumes (with storage IDs), or an error if any creation fails. // Any volumes processed before or during a failure are returned alongside the error so they can be persisted on the actor. -func createActorVolumes(ctx context.Context, registry VolumePluginRegistry, scLister storagev1listers.StorageClassLister, actorUID string, template *ateapi.ActorTemplate, volumesToCreate []*ateapi.ExternalVolumeStatus) (resultVolumes []*ateapi.ExternalVolumeStatus, err error) { +func createActorVolumes(ctx context.Context, registry VolumePluginRegistry, classes externalVolumeClassGetter, scLister storagev1listers.StorageClassLister, actorUID string, template *ateapi.ActorTemplate, volumesToCreate []*ateapi.ExternalVolumeStatus) (resultVolumes []*ateapi.ExternalVolumeStatus, err error) { resultVolumes = make([]*ateapi.ExternalVolumeStatus, 0, len(volumesToCreate)) var currentIdx int @@ -102,28 +154,24 @@ func createActorVolumes(ctx context.Context, registry VolumePluginRegistry, scLi actVolID := actorVolumeID(actorUID, volName) - scName := specVol.GetExternal().GetTemplate().GetStorageClassName() - sc, err := scLister.Get(scName) + class, err := resolveVolumeClass(ctx, classes, scLister, specVol.GetExternal().GetTemplate()) if err != nil { - if k8serrors.IsNotFound(err) { - return resultVolumes, apierror.FailedPrecondition("StorageClass %q not found", scName) - } - return resultVolumes, apierror.Internal("failed to get StorageClass %q: %v", scName, err) + return resultVolumes, err } - if sc.Provisioner != vol.GetVolumeType() { - return resultVolumes, apierror.FailedPrecondition("volume %q has mismatched type %q (expected %q from StorageClass %q)", volName, vol.GetVolumeType(), sc.Provisioner, scName) + if class.driver != vol.GetVolumeType() { + return resultVolumes, apierror.FailedPrecondition("volume %q has mismatched type %q (expected %q from %s)", volName, vol.GetVolumeType(), class.driver, class.label) } plugin, err := registry.GetPlugin(ctx, vol.GetVolumeType()) if err != nil { - return resultVolumes, apierror.FailedPrecondition("failed to get volume plugin for driver %q (StorageClass %q): %v", sc.Provisioner, scName, err) + return resultVolumes, apierror.FailedPrecondition("failed to get volume plugin for driver %q (%s): %v", class.driver, class.label, err) } resp, volErr := plugin.CreateVolume(ctx, volume.CreateVolumeRequest{ Name: actVolID, CapacityBytes: specVol.GetExternal().GetTemplate().GetCapacityBytes(), - Parameters: sc.Parameters, + Parameters: class.params, }) if volErr != nil { return resultVolumes, apierror.Internal("failed to create volume %q: %v", specVol.GetName(), volErr) @@ -137,7 +185,7 @@ func createActorVolumes(ctx context.Context, registry VolumePluginRegistry, scLi resultVolumes = append(resultVolumes, &ateapi.ExternalVolumeStatus{ Name: volName, StorageVolumeId: resp.VolumeID, - VolumeType: sc.Provisioner, + VolumeType: class.driver, VolumeContext: resp.VolumeContext, }) } diff --git a/cmd/ateapi/internal/controlapi/volumes_test.go b/cmd/ateapi/internal/controlapi/volumes_test.go index a7366a0c9f..5603357dcf 100644 --- a/cmd/ateapi/internal/controlapi/volumes_test.go +++ b/cmd/ateapi/internal/controlapi/volumes_test.go @@ -58,6 +58,24 @@ func (f *fakeStorageClassLister) Get(name string) (*storagev1.StorageClass, erro var _ storagev1listers.StorageClassLister = (*fakeStorageClassLister)(nil) +// fakeExternalVolumeClassGetter serves classes from a map and reports a +// missing name the way ServiceImpl does. +type fakeExternalVolumeClassGetter struct { + classes map[string]*ateapi.ExternalVolumeClass + getErr error +} + +func (f *fakeExternalVolumeClassGetter) GetExternalVolumeClass(_ context.Context, name string) (*ateapi.ExternalVolumeClass, error) { + if f.getErr != nil { + return nil, f.getErr + } + class, ok := f.classes[name] + if !ok { + return nil, apierror.NotFound("ExternalVolumeClass %s not found", name) + } + return class, nil +} + func TestActorVolumesStorageClassErrors(t *testing.T) { ctx := context.Background() tmpl := &ateapi.ActorTemplate{ @@ -91,7 +109,7 @@ func TestActorVolumesStorageClassErrors(t *testing.T) { t.Run(tt.name, func(t *testing.T) { lister := &fakeStorageClassLister{getErr: tt.getErr} t.Run("initial", func(t *testing.T) { - _, err := initialExternalVolumes(ctx, lister, tmpl) + _, err := initialExternalVolumes(ctx, nil, lister, tmpl) if got := apierror.Code(err); got != tt.wantCode { t.Fatalf("initialExternalVolumes() code = %v, want %v; error = %v", got, tt.wantCode, err) } @@ -100,7 +118,7 @@ func TestActorVolumesStorageClassErrors(t *testing.T) { } }) t.Run("create", func(t *testing.T) { - res, err := createActorVolumes(ctx, &mockPluginRegistry{}, lister, "actor-uid-123", tmpl, volumes) + res, err := createActorVolumes(ctx, &mockPluginRegistry{}, nil, lister, "actor-uid-123", tmpl, volumes) if got := apierror.Code(err); got != tt.wantCode { t.Fatalf("createActorVolumes() code = %v, want %v; error = %v", got, tt.wantCode, err) } @@ -163,7 +181,7 @@ func TestInitialActorVolumes(t *testing.T) { }, }, } - initVols, err := initialExternalVolumes(context.Background(), scLister, tmpl) + initVols, err := initialExternalVolumes(context.Background(), nil, scLister, tmpl) if err != nil { t.Fatalf("initialExternalVolumes failed: %v", err) } @@ -322,7 +340,7 @@ func TestCreateActorVolumes(t *testing.T) { } } scLister := &fakeStorageClassLister{storageClasses: scs} - res, err := createActorVolumes(ctx, registry, scLister, "actor-uid-123", tt.tmpl, tt.inputVolumes) + res, err := createActorVolumes(ctx, registry, nil, scLister, "actor-uid-123", tt.tmpl, tt.inputVolumes) if (err != nil) != tt.wantErr { t.Errorf("createActorVolumes() error = %v, wantErr %v", err, tt.wantErr) } @@ -333,6 +351,138 @@ func TestCreateActorVolumes(t *testing.T) { } } +func TestResolveExternalVolumeClass(t *testing.T) { + ref := &ateapi.ObjectRef{Name: "gold"} + for _, tt := range []struct { + name string + getter *fakeExternalVolumeClassGetter + wantCode codes.Code + wantDriver string + wantParams map[string]string + }{{ + name: "found", + getter: &fakeExternalVolumeClassGetter{classes: map[string]*ateapi.ExternalVolumeClass{ + "gold": {DriverName: "mock-standard", Parameters: map[string]string{"tier": "gold"}}, + }}, + wantCode: codes.OK, + wantDriver: "mock-standard", + wantParams: map[string]string{"tier": "gold"}, + }, { + name: "missing", + getter: &fakeExternalVolumeClassGetter{}, + wantCode: codes.FailedPrecondition, + }, { + name: "lookup fails", + getter: &fakeExternalVolumeClassGetter{getErr: errors.New("database unavailable")}, + wantCode: codes.Internal, + }} { + t.Run(tt.name, func(t *testing.T) { + driver, params, err := resolveExternalVolumeClass(context.Background(), tt.getter, ref) + if got := apierror.Code(err); got != tt.wantCode { + t.Fatalf("resolveExternalVolumeClass() code = %v, want %v; error = %v", got, tt.wantCode, err) + } + if err != nil { + if !strings.Contains(err.Error(), `ExternalVolumeClass "gold"`) { + t.Errorf("resolveExternalVolumeClass() error does not name the class: %v", err) + } + return + } + if driver != tt.wantDriver { + t.Errorf("resolveExternalVolumeClass() driver = %q, want %q", driver, tt.wantDriver) + } + if diff := cmp.Diff(tt.wantParams, params); diff != "" { + t.Errorf("resolveExternalVolumeClass() params mismatch (-want +got):\n%s", diff) + } + }) + } +} + +func TestActorVolumesFromExternalVolumeClass(t *testing.T) { + ctx := context.Background() + tmpl := &ateapi.ActorTemplate{ + Volumes: []*ateapi.Volume{{ + Name: "data-vol", + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ + ExternalVolumeClass: &ateapi.ObjectRef{Name: "gold"}, + CapacityBytes: 1 << 30, + }}, + }}, + } + classes := &fakeExternalVolumeClassGetter{classes: map[string]*ateapi.ExternalVolumeClass{ + "gold": {DriverName: "mock-standard", Parameters: map[string]string{"tier": "gold"}}, + }} + registry := &mockPluginRegistry{plugins: map[string]volume.VolumePluginControlPlane{ + "mock-standard": volume.NewMockVolumePlugin(), + }} + + t.Run("initial volume takes the class driver as its type", func(t *testing.T) { + got, err := initialExternalVolumes(ctx, classes, nil, tmpl) + if err != nil { + t.Fatalf("initialExternalVolumes() failed: %v", err) + } + want := []*ateapi.ExternalVolumeStatus{{Name: "data-vol", VolumeType: "mock-standard"}} + if diff := cmp.Diff(want, got, protocmp.Transform()); diff != "" { + t.Errorf("initialExternalVolumes() mismatch (-want +got):\n%s", diff) + } + }) + + t.Run("create passes the class parameters to the driver", func(t *testing.T) { + input := []*ateapi.ExternalVolumeStatus{{Name: "data-vol", VolumeType: "mock-standard"}} + got, err := createActorVolumes(ctx, registry, classes, nil, "actor-uid-123", tmpl, input) + if err != nil { + t.Fatalf("createActorVolumes() failed: %v", err) + } + want := []*ateapi.ExternalVolumeStatus{{ + Name: "data-vol", + StorageVolumeId: "mock-vol-substrate-actor-uid-123-data-vol", + VolumeType: "mock-standard", + VolumeContext: map[string]string{"tier": "gold"}, + }} + if diff := cmp.Diff(want, got, protocmp.Transform()); diff != "" { + t.Errorf("createActorVolumes() mismatch (-want +got):\n%s", diff) + } + }) + + t.Run("create rejects a volume whose type differs from the class driver", func(t *testing.T) { + input := []*ateapi.ExternalVolumeStatus{{Name: "data-vol", VolumeType: "mock-fast"}} + got, err := createActorVolumes(ctx, registry, classes, nil, "actor-uid-123", tmpl, input) + if code := apierror.Code(err); code != codes.FailedPrecondition { + t.Fatalf("createActorVolumes() code = %v, want %v; error = %v", code, codes.FailedPrecondition, err) + } + if !strings.Contains(err.Error(), `from ExternalVolumeClass "gold"`) { + t.Errorf("createActorVolumes() error does not name the class: %v", err) + } + if diff := cmp.Diff(input, got, protocmp.Transform()); diff != "" { + t.Errorf("createActorVolumes() did not preserve pending volumes (-want +got):\n%s", diff) + } + }) + + t.Run("missing class is a failed precondition", func(t *testing.T) { + missing := &fakeExternalVolumeClassGetter{} + if _, err := initialExternalVolumes(ctx, missing, nil, tmpl); apierror.Code(err) != codes.FailedPrecondition { + t.Errorf("initialExternalVolumes() error = %v, want FailedPrecondition", err) + } + input := []*ateapi.ExternalVolumeStatus{{Name: "data-vol", VolumeType: "mock-standard"}} + got, err := createActorVolumes(ctx, registry, missing, nil, "actor-uid-123", tmpl, input) + if code := apierror.Code(err); code != codes.FailedPrecondition { + t.Fatalf("createActorVolumes() code = %v, want %v; error = %v", code, codes.FailedPrecondition, err) + } + if diff := cmp.Diff(input, got, protocmp.Transform()); diff != "" { + t.Errorf("createActorVolumes() did not preserve pending volumes (-want +got):\n%s", diff) + } + }) + + t.Run("template with no class is a failed precondition", func(t *testing.T) { + noClass := &ateapi.ActorTemplate{Volumes: []*ateapi.Volume{{ + Name: "data-vol", + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: 1 << 30}}, + }}} + if _, err := initialExternalVolumes(ctx, classes, nil, noClass); apierror.Code(err) != codes.FailedPrecondition { + t.Errorf("initialExternalVolumes() error = %v, want FailedPrecondition", err) + } + }) +} + // emptyIDVolumePlugin provisions volumes without returning an ID. type emptyIDVolumePlugin struct { volume.VolumePluginControlPlane @@ -357,7 +507,7 @@ func TestCreateActorVolumesRejectsEmptyPluginID(t *testing.T) { }} input := []*ateapi.ExternalVolumeStatus{{Name: "data-vol", VolumeType: "mock-standard"}} - res, err := createActorVolumes(context.Background(), registry, scLister, "actor-uid-123", tmpl, input) + res, err := createActorVolumes(context.Background(), registry, nil, scLister, "actor-uid-123", tmpl, input) if got := apierror.Code(err); got != codes.Internal { t.Fatalf("createActorVolumes() code = %v, want %v; error = %v", got, codes.Internal, err) } diff --git a/cmd/ateapi/internal/controlapi/workflow.go b/cmd/ateapi/internal/controlapi/workflow.go index c8579c64e5..834c481e27 100644 --- a/cmd/ateapi/internal/controlapi/workflow.go +++ b/cmd/ateapi/internal/controlapi/workflow.go @@ -187,6 +187,7 @@ type actorWorkflowStore interface { MarkTagForDeletion(ctx context.Context, tagRef resources.TagRef, precondition store.DeletePreconditions, mutate func(toUpdate *ateapi.Tag) error) (*ateapi.Tag, error) DeleteTag(ctx context.Context, tagRef resources.TagRef, precondition store.DeletePreconditions) (*ateapi.Tag, error) GetActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef) (*ateapi.ActorTemplate, error) + GetExternalVolumeClass(ctx context.Context, name string) (*ateapi.ExternalVolumeClass, error) MarkActorTemplateForDeletion(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.DeletePreconditions, mutate func(toUpdate *ateapi.ActorTemplate) error) (*ateapi.ActorTemplate, error) DeleteActorTemplate(ctx context.Context, templateRef resources.ActorTemplateRef, precondition store.DeletePreconditions) (*ateapi.ActorTemplate, error) AcquireLease(ctx context.Context, key string) (*store.Lease, error) diff --git a/cmd/ateapi/internal/controlapi/workflow_resume.go b/cmd/ateapi/internal/controlapi/workflow_resume.go index 324a16eda6..ccd34726bc 100644 --- a/cmd/ateapi/internal/controlapi/workflow_resume.go +++ b/cmd/ateapi/internal/controlapi/workflow_resume.go @@ -206,7 +206,7 @@ func (w *ActorWorkflow) ensureVolumesCreated(ctx context.Context, actorRef resou return nil, apierror.FailedPrecondition("cannot create volumes for Actor %s in state %s", actorRef, st) } - volumes, createErr := createActorVolumes(ctx, w.pluginRegistry, w.storageClassLister, actor.GetMetadata().GetUid(), actorTemplate, actor.GetStatus().GetExternalVolumes().GetVolumes()) + volumes, createErr := createActorVolumes(ctx, w.pluginRegistry, w.store, w.storageClassLister, actor.GetMetadata().GetUid(), actorTemplate, actor.GetStatus().GetExternalVolumes().GetVolumes()) // createActorVolumes reports the state it got to even when it fails, so both // paths persist the same field. updatePrecondition := store.PreconditionFrom(actor) diff --git a/internal/volume/plugin.go b/internal/volume/plugin.go index a3f9ca3aa9..c2a44991fe 100644 --- a/internal/volume/plugin.go +++ b/internal/volume/plugin.go @@ -24,7 +24,7 @@ type CreateVolumeRequest struct { Name string // CapacityBytes is the requested size in bytes. CapacityBytes int64 - // Parameters are the driver-specific parameters from the StorageClass. + // Parameters are the driver-specific parameters from the volume's class. Parameters map[string]string } From 33d6e7ffb87c45f2d1018ebb49a3dd2cb76bba53 Mon Sep 17 00:00:00 2001 From: Vu Le Date: Tue, 10 Nov 2026 19:50:25 +0000 Subject: [PATCH 12/30] ExternalVolumeClass printer and unit tests Signed-off-by: Vu Le --- .../internal/printer/external_volume_class.go | 66 +++++++++++++++ .../printer/external_volume_class_test.go | 82 +++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 cmd/kubectl-ate/internal/printer/external_volume_class.go create mode 100644 cmd/kubectl-ate/internal/printer/external_volume_class_test.go diff --git a/cmd/kubectl-ate/internal/printer/external_volume_class.go b/cmd/kubectl-ate/internal/printer/external_volume_class.go new file mode 100644 index 0000000000..457d4413cd --- /dev/null +++ b/cmd/kubectl-ate/internal/printer/external_volume_class.go @@ -0,0 +1,66 @@ +// Copyright 2026 The Agent Substrate Authors +// +// 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 printer + +import ( + "cmp" + "fmt" + "io" + "maps" + "slices" + "strings" + "text/tabwriter" + + "go.ate.dev/substrate/api/ateapi/v1" +) + +func formatParameters(params map[string]string) string { + if len(params) == 0 { + return "-" + } + keys := slices.Sorted(maps.Keys(params)) + for i, k := range keys { + keys[i] = k + "=" + params[k] + } + return strings.Join(keys, ",") +} + +// PrintExternalVolumeClassesTo prints a slice of external volume classes to the provided writer. +func PrintExternalVolumeClassesTo(out io.Writer, classes []*ateapi.ExternalVolumeClass, format string) error { + slices.SortFunc(classes, func(a, b *ateapi.ExternalVolumeClass) int { + return cmp.Compare(a.GetMetadata().GetName(), b.GetMetadata().GetName()) + }) + switch format { + case "json", "yaml": + return printProto(out, &ateapi.ListExternalVolumeClassesResponse{ExternalVolumeClasses: classes}, format) + case "table": + w := tabwriter.NewWriter(out, 0, 0, 3, ' ', 0) + fmt.Fprintln(w, "NAME\tDRIVER\tPARAMETERS\tAGE") + for _, c := range classes { + fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", c.GetMetadata().GetName(), c.GetDriverName(), formatParameters(c.GetParameters()), formatAge(c.GetMetadata().GetCreateTime())) + } + return w.Flush() + default: + return fmt.Errorf("unsupported format %q", format) + } +} + +// PrintExternalVolumeClassTo prints a single external volume class to the provided writer. +func PrintExternalVolumeClassTo(out io.Writer, class *ateapi.ExternalVolumeClass, format string) error { + if format == "json" || format == "yaml" { + return printProto(out, class, format) + } + return PrintExternalVolumeClassesTo(out, []*ateapi.ExternalVolumeClass{class}, format) +} diff --git a/cmd/kubectl-ate/internal/printer/external_volume_class_test.go b/cmd/kubectl-ate/internal/printer/external_volume_class_test.go new file mode 100644 index 0000000000..456f841efe --- /dev/null +++ b/cmd/kubectl-ate/internal/printer/external_volume_class_test.go @@ -0,0 +1,82 @@ +// Copyright 2026 The Agent Substrate Authors +// +// 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 printer + +import ( + "bytes" + "strings" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" + "google.golang.org/protobuf/types/known/timestamppb" +) + +func TestPrintExternalVolumeClasses(t *testing.T) { + now := time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC) + pinNow(t, now) + + fastSSD := &ateapi.ExternalVolumeClass{ + Metadata: &ateapi.ResourceMetadata{Name: "fast-ssd", Uid: "u-1", Version: 1, CreateTime: timestamppb.New(now.Add(-10 * time.Minute))}, + DriverName: "pd.csi.storage.gke.io", + Parameters: map[string]string{"type": "pd-ssd", "replication-type": "none"}, + } + standardRWO := &ateapi.ExternalVolumeClass{ + Metadata: &ateapi.ResourceMetadata{Name: "standard-rwo", CreateTime: timestamppb.New(now.Add(-5 * time.Hour))}, + DriverName: "pd.csi.storage.gke.io", + } + + var buf bytes.Buffer + if err := PrintExternalVolumeClassesTo(&buf, []*ateapi.ExternalVolumeClass{standardRWO, fastSSD}, "table"); err != nil { + t.Fatalf("PrintExternalVolumeClassesTo(table) error = %v", err) + } + wantTable := "NAME DRIVER PARAMETERS AGE\n" + + "fast-ssd pd.csi.storage.gke.io replication-type=none,type=pd-ssd 10m\n" + + "standard-rwo pd.csi.storage.gke.io - 5h\n" + if diff := cmp.Diff(wantTable, buf.String()); diff != "" { + t.Errorf("table mismatch (-want +got):\n%s", diff) + } + + for _, tc := range []struct { + name, format string + single bool + wantSub []string + wantErr bool + }{ + {name: "list json", format: "json", wantSub: []string{`"externalVolumeClasses"`, `"driverName": "pd.csi.storage.gke.io"`}}, + {name: "list yaml", format: "yaml", wantSub: []string{"externalVolumeClasses:", "driverName: pd.csi.storage.gke.io"}}, + {name: "single yaml bare object", single: true, format: "yaml", wantSub: []string{"driverName: pd.csi.storage.gke.io", "uid: u-1", `version: "1"`}}, + {name: "single table", single: true, format: "table", wantSub: []string{"NAME", "fast-ssd pd.csi.storage.gke.io replication-type=none,type=pd-ssd 10m"}}, + {name: "unsupported format", single: true, format: "xml", wantErr: true}, + } { + t.Run(tc.name, func(t *testing.T) { + var out bytes.Buffer + err := PrintExternalVolumeClassesTo(&out, []*ateapi.ExternalVolumeClass{fastSSD}, tc.format) + if tc.single { + out.Reset() + err = PrintExternalVolumeClassTo(&out, fastSSD, tc.format) + } + if (err != nil) != tc.wantErr { + t.Fatalf("error = %v, wantErr %v", err, tc.wantErr) + } + for _, w := range tc.wantSub { + if !strings.Contains(out.String(), w) { + t.Errorf("output = %q, want substring %q", out.String(), w) + } + } + }) + } +} From 8de3dccbc960e2fdf9967362fc45a2269e333d88 Mon Sep 17 00:00:00 2001 From: Vu Le Date: Tue, 10 Nov 2026 19:50:41 +0000 Subject: [PATCH 13/30] kubectl-ate get/create/delete commands and unit tests Signed-off-by: Vu Le --- .../internal/cmd/external_volume_class.go | 176 ++++++++++++++++++ .../cmd/external_volume_class_test.go | 163 ++++++++++++++++ 2 files changed, 339 insertions(+) create mode 100644 cmd/kubectl-ate/internal/cmd/external_volume_class.go create mode 100644 cmd/kubectl-ate/internal/cmd/external_volume_class_test.go diff --git a/cmd/kubectl-ate/internal/cmd/external_volume_class.go b/cmd/kubectl-ate/internal/cmd/external_volume_class.go new file mode 100644 index 0000000000..8580515b2e --- /dev/null +++ b/cmd/kubectl-ate/internal/cmd/external_volume_class.go @@ -0,0 +1,176 @@ +// Copyright 2026 The Agent Substrate Authors +// +// 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" + "io" + + "github.com/spf13/cobra" + "go.ate.dev/substrate/api/ateapi/v1" + "go.ate.dev/substrate/cmd/kubectl-ate/internal/printer" + "google.golang.org/grpc" + "google.golang.org/protobuf/encoding/protojson" +) + +var ( + createExternalVolumeClassFilenameFlag string + deleteExternalVolumeClassGuard deleteGuardFlags +) + +type externalVolumeClassClient interface { + GetExternalVolumeClass(ctx context.Context, in *ateapi.GetExternalVolumeClassRequest, opts ...grpc.CallOption) (*ateapi.ExternalVolumeClass, error) + ListExternalVolumeClasses(ctx context.Context, in *ateapi.ListExternalVolumeClassesRequest, opts ...grpc.CallOption) (*ateapi.ListExternalVolumeClassesResponse, error) + CreateExternalVolumeClass(ctx context.Context, in *ateapi.CreateExternalVolumeClassRequest, opts ...grpc.CallOption) (*ateapi.ExternalVolumeClass, error) + DeleteExternalVolumeClass(ctx context.Context, in *ateapi.DeleteExternalVolumeClassRequest, opts ...grpc.CallOption) (*ateapi.ExternalVolumeClass, error) +} + +var getExternalVolumeClassesCmd = &cobra.Command{ + Use: "external-volume-class [name ...]", + Aliases: []string{"external-volume-classes"}, + Short: "List all external volume classes or get one or more external volume classes", + Long: "List or get external volume classes.", + Args: cobra.ArbitraryArgs, + RunE: func(cmd *cobra.Command, args []string) error { + apiClient, err := newAPIClient(cmd) + if err != nil { + return fmt.Errorf("failed to connect to ate-api-server: %w", err) + } + defer apiClient.Close() + return runGetExternalVolumeClasses(cmd.Context(), apiClient, cmd.OutOrStdout(), outputFmt, args) + }, +} + +var createExternalVolumeClassCmd = &cobra.Command{ + Use: "external-volume-class -f ", + Aliases: []string{"external-volume-classes"}, + Short: "Create an external volume class from a manifest", + Long: `Create an external volume class from a single YAML or JSON manifest holding one ateapi.ExternalVolumeClass message in protojson form (as printed by "kubectl ate get external-volume-class -o yaml"). External volume classes are global-scoped and immutable.`, + Args: noArgs("the external volume class name comes from the manifest passed to -f/--filename", "filename"), + RunE: func(cmd *cobra.Command, args []string) error { + class, err := loadExternalVolumeClassManifest(cmd.InOrStdin(), createExternalVolumeClassFilenameFlag) + if err != nil { + return err + } + apiClient, err := newAPIClient(cmd) + if err != nil { + return fmt.Errorf("failed to connect to ate-api-server: %w", err) + } + defer apiClient.Close() + return runCreateExternalVolumeClass(cmd.Context(), apiClient, cmd.OutOrStdout(), outputFmt, class) + }, +} + +var deleteExternalVolumeClassCmd = &cobra.Command{ + Use: "external-volume-class ", + Aliases: []string{"external-volume-classes"}, + Short: "Delete an external volume class", + Long: "Delete an external volume class. Pass --uid and/or --version to guard the delete against a concurrent replacement.", + Args: exactlyOneArg(""), + RunE: func(cmd *cobra.Command, args []string) error { + opts, err := deleteOptionsFromFlags(deleteGuardFlags{ + uidSet: cmd.Flags().Changed("uid"), + uid: deleteExternalVolumeClassGuard.uid, + versionSet: cmd.Flags().Changed("version"), + version: deleteExternalVolumeClassGuard.version, + }) + if err != nil { + return wrapUsageError(err) + } + apiClient, err := newAPIClient(cmd) + if err != nil { + return fmt.Errorf("failed to connect to ate-api-server: %w", err) + } + defer apiClient.Close() + return runDeleteExternalVolumeClass(cmd.Context(), apiClient, cmd.OutOrStdout(), args[0], opts) + }, +} + +func runGetExternalVolumeClasses(ctx context.Context, client externalVolumeClassClient, out io.Writer, format string, names []string) error { + if len(names) > 0 { + classes := make([]*ateapi.ExternalVolumeClass, 0, len(names)) + for _, name := range names { + resp, err := client.GetExternalVolumeClass(ctx, &ateapi.GetExternalVolumeClassRequest{ExternalVolumeClass: &ateapi.ObjectRef{Name: name}}) + if err != nil { + return fmt.Errorf("failed to get external volume class %q: %w", name, err) + } + classes = append(classes, resp) + } + if len(classes) == 1 { + return printer.PrintExternalVolumeClassTo(out, classes[0], format) + } + return printer.PrintExternalVolumeClassesTo(out, classes, format) + } + var allClasses []*ateapi.ExternalVolumeClass + for pageToken := ""; ; { + resp, err := client.ListExternalVolumeClasses(ctx, &ateapi.ListExternalVolumeClassesRequest{Options: &ateapi.ListOptions{PageSize: 1000, PageToken: pageToken}}) + if err != nil { + return fmt.Errorf("failed to list external volume classes: %w", err) + } + allClasses = append(allClasses, resp.GetExternalVolumeClasses()...) + if pageToken = resp.GetNextPageToken(); pageToken == "" { + break + } + } + return printer.PrintExternalVolumeClassesTo(out, allClasses, format) +} + +func runCreateExternalVolumeClass(ctx context.Context, client externalVolumeClassClient, out io.Writer, format string, class *ateapi.ExternalVolumeClass) error { + resp, err := client.CreateExternalVolumeClass(ctx, &ateapi.CreateExternalVolumeClassRequest{ExternalVolumeClass: class}) + if err != nil { + return fmt.Errorf("failed to create external volume class: %w", err) + } + return printer.PrintExternalVolumeClassTo(out, resp, format) +} + +func runDeleteExternalVolumeClass(ctx context.Context, client externalVolumeClassClient, out io.Writer, name string, opts *ateapi.DeleteOptions) error { + if _, err := client.DeleteExternalVolumeClass(ctx, &ateapi.DeleteExternalVolumeClassRequest{ExternalVolumeClass: &ateapi.ObjectRef{Name: name}, Options: opts}); err != nil { + return fmt.Errorf("failed to delete external volume class: %w", err) + } + fmt.Fprintf(out, "external volume class %q deleted\n", name) + return nil +} + +func loadExternalVolumeClassManifest(in io.Reader, path string) (*ateapi.ExternalVolumeClass, error) { + data, err := readFileOrStdin(in, path) + if err != nil { + return nil, err + } + jsonData, err := manifestToJSON(data) + if err != nil { + return nil, fmt.Errorf("failed to parse external volume class manifest %q: %w", path, err) + } + class := &ateapi.ExternalVolumeClass{} + if err := protojson.Unmarshal(jsonData, class); err != nil { + return nil, fmt.Errorf("failed to parse external volume class manifest %q: invalid ExternalVolumeClass: %w", path, err) + } + if got := class.GetMetadata().GetAtespace(); got != "" { + return nil, fmt.Errorf("external volume class is global-scoped: metadata.atespace must be empty (got %q)", got) + } + if class.GetMetadata().GetName() == "" { + return nil, fmt.Errorf("failed to parse external volume class manifest %q: metadata.name is required", path) + } + return class, nil +} + +func init() { + getCmd.AddCommand(getExternalVolumeClassesCmd) + createExternalVolumeClassCmd.Flags().StringVarP(&createExternalVolumeClassFilenameFlag, "filename", "f", "", "manifest file holding a single JSON or YAML external-volume-class document, or - for stdin") + createCmd.AddCommand(createExternalVolumeClassCmd) + deleteExternalVolumeClassCmd.Flags().StringVar(&deleteExternalVolumeClassGuard.uid, "uid", "", "require the external volume class to have this UID before deleting") + deleteExternalVolumeClassCmd.Flags().Int64Var(&deleteExternalVolumeClassGuard.version, "version", 0, "require the external volume class to be at this version before deleting") + deleteCmd.AddCommand(deleteExternalVolumeClassCmd) +} diff --git a/cmd/kubectl-ate/internal/cmd/external_volume_class_test.go b/cmd/kubectl-ate/internal/cmd/external_volume_class_test.go new file mode 100644 index 0000000000..4baece48aa --- /dev/null +++ b/cmd/kubectl-ate/internal/cmd/external_volume_class_test.go @@ -0,0 +1,163 @@ +// Copyright 2026 The Agent Substrate Authors +// +// 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 ( + "bytes" + "context" + "strings" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "go.ate.dev/substrate/api/ateapi/v1" + "go.ate.dev/substrate/cmd/kubectl-ate/internal/printer" + "google.golang.org/grpc" + "google.golang.org/protobuf/testing/protocmp" + "google.golang.org/protobuf/types/known/timestamppb" +) + +func TestExternalVolumeClassCommandArgs(t *testing.T) { + runCommandArgsTests(t, []commandArgsTest{ + {name: "list", command: getExternalVolumeClassesCmd}, + {name: "get", command: getExternalVolumeClassesCmd, args: []string{"fast-ssd"}}, + {name: "get multiple", command: getExternalVolumeClassesCmd, args: []string{"fast-ssd", "standard-rwo"}}, + {name: "delete", command: deleteExternalVolumeClassCmd, args: []string{"fast-ssd"}}, + {name: "delete missing name", command: deleteExternalVolumeClassCmd, wantErr: true}, + {name: "delete extra name", command: deleteExternalVolumeClassCmd, args: []string{"a", "b"}, wantErr: true}, + }) +} + +func TestLoadExternalVolumeClassManifest(t *testing.T) { + t.Parallel() + wantFastSSD := &ateapi.ExternalVolumeClass{Metadata: &ateapi.ResourceMetadata{Name: "fast-ssd"}, DriverName: "pd.csi.storage.gke.io", Parameters: map[string]string{"type": "pd-ssd"}} + for _, tc := range []struct { + name, manifest, wantErr string + want *ateapi.ExternalVolumeClass + }{ + {name: "camelCase yaml", manifest: "metadata: {name: fast-ssd}\ndriverName: pd.csi.storage.gke.io\nparameters: {type: pd-ssd}\n", want: wantFastSSD}, + {name: "snake_case yaml", manifest: "metadata: {name: fast-ssd}\ndriver_name: pd.csi.storage.gke.io\nparameters: {type: pd-ssd}\n", want: wantFastSSD}, + {name: "json input", manifest: `{"metadata": {"name": "fast-ssd"}, "driverName": "pd.csi.storage.gke.io", "parameters": {"type": "pd-ssd"}}`, want: wantFastSSD}, + {name: "missing metadata.name", manifest: "driverName: pd.csi.storage.gke.io", wantErr: "metadata.name is required"}, + {name: "atespace set", manifest: "metadata: {atespace: team-a, name: fast-ssd}", wantErr: "metadata.atespace must be empty"}, + {name: "unknown field", manifest: "metadata: {name: fast-ssd}\nprovisioner: pd.csi.storage.gke.io", wantErr: "invalid ExternalVolumeClass"}, + {name: "empty", manifest: "", wantErr: "manifest is empty"}, + {name: "multi-document yaml", manifest: "metadata: {name: a}\n---\nmetadata: {name: b}\n", wantErr: "manifest holds more than one document"}, + } { + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + got, err := loadExternalVolumeClassManifest(strings.NewReader(tc.manifest), "-") + if tc.wantErr != "" { + if err == nil || !strings.Contains(err.Error(), tc.wantErr) { + t.Fatalf("loadExternalVolumeClassManifest() error = %v, want %q", err, tc.wantErr) + } + return + } + if err != nil || cmp.Diff(tc.want, got, protocmp.Transform()) != "" { + t.Fatalf("loadExternalVolumeClassManifest() = (%v, %v), want %v", got, err, tc.want) + } + }) + } + + t.Run("yaml round-trip", func(t *testing.T) { + t.Parallel() + serverObj := &ateapi.ExternalVolumeClass{ + Metadata: &ateapi.ResourceMetadata{Name: "fast-ssd", Uid: "u-1", Version: 1, CreateTime: timestamppb.New(time.Date(2026, 1, 1, 11, 55, 0, 0, time.UTC))}, + DriverName: "pd.csi.storage.gke.io", + Parameters: map[string]string{"type": "pd-ssd"}, + } + var yamlOut bytes.Buffer + if err := printer.PrintExternalVolumeClassTo(&yamlOut, serverObj, "yaml"); err != nil { + t.Fatalf("PrintExternalVolumeClassTo(yaml) error = %v", err) + } + parsed, err := loadExternalVolumeClassManifest(&yamlOut, "-") + if err != nil || cmp.Diff(serverObj, parsed, protocmp.Transform()) != "" { + t.Fatalf("round-trip = (%v, %v), want %v", parsed, err, serverObj) + } + }) +} + +type fakeExternalVolumeClassClient struct { + byName map[string]*ateapi.ExternalVolumeClass + listPages []*ateapi.ListExternalVolumeClassesResponse + listReqs []*ateapi.ListExternalVolumeClassesRequest + createReq *ateapi.CreateExternalVolumeClassRequest + deleteReq *ateapi.DeleteExternalVolumeClassRequest +} + +func (f *fakeExternalVolumeClassClient) GetExternalVolumeClass(_ context.Context, req *ateapi.GetExternalVolumeClassRequest, _ ...grpc.CallOption) (*ateapi.ExternalVolumeClass, error) { + return f.byName[req.GetExternalVolumeClass().GetName()], nil +} +func (f *fakeExternalVolumeClassClient) ListExternalVolumeClasses(_ context.Context, req *ateapi.ListExternalVolumeClassesRequest, _ ...grpc.CallOption) (*ateapi.ListExternalVolumeClassesResponse, error) { + f.listReqs = append(f.listReqs, req) + if len(f.listPages) == 0 { + return &ateapi.ListExternalVolumeClassesResponse{}, nil + } + page := f.listPages[0] + f.listPages = f.listPages[1:] + return page, nil +} +func (f *fakeExternalVolumeClassClient) CreateExternalVolumeClass(_ context.Context, req *ateapi.CreateExternalVolumeClassRequest, _ ...grpc.CallOption) (*ateapi.ExternalVolumeClass, error) { + f.createReq = req + return req.GetExternalVolumeClass(), nil +} +func (f *fakeExternalVolumeClassClient) DeleteExternalVolumeClass(_ context.Context, req *ateapi.DeleteExternalVolumeClassRequest, _ ...grpc.CallOption) (*ateapi.ExternalVolumeClass, error) { + f.deleteReq = req + return &ateapi.ExternalVolumeClass{Metadata: &ateapi.ResourceMetadata{Name: req.GetExternalVolumeClass().GetName()}}, nil +} + +func TestExternalVolumeClassRunners(t *testing.T) { + ctx := context.Background() + fastSSD := &ateapi.ExternalVolumeClass{Metadata: &ateapi.ResourceMetadata{Name: "fast-ssd", Version: 1}, DriverName: "pd.csi.storage.gke.io", Parameters: map[string]string{"type": "pd-ssd"}} + standardRWO := &ateapi.ExternalVolumeClass{Metadata: &ateapi.ResourceMetadata{Name: "standard-rwo", Version: 1}, DriverName: "pd.csi.storage.gke.io"} + + client := &fakeExternalVolumeClassClient{ + byName: map[string]*ateapi.ExternalVolumeClass{"fast-ssd": fastSSD, "standard-rwo": standardRWO}, + listPages: []*ateapi.ListExternalVolumeClassesResponse{ + {ExternalVolumeClasses: []*ateapi.ExternalVolumeClass{standardRWO}, NextPageToken: "page-2"}, + {ExternalVolumeClasses: []*ateapi.ExternalVolumeClass{fastSSD}}, + }, + } + var out bytes.Buffer + if err := runGetExternalVolumeClasses(ctx, client, &out, "yaml", []string{"fast-ssd"}); err != nil || strings.Contains(out.String(), "externalVolumeClasses:") { + t.Fatalf("single get err = %v, out = %s", err, out.String()) + } + out.Reset() + if err := runGetExternalVolumeClasses(ctx, client, &out, "yaml", []string{"standard-rwo", "fast-ssd"}); err != nil || !strings.Contains(out.String(), "externalVolumeClasses:") { + t.Fatalf("multi get err = %v, out = %s", err, out.String()) + } + out.Reset() + if err := runGetExternalVolumeClasses(ctx, client, &out, "yaml", nil); err != nil || len(client.listReqs) != 2 || client.listReqs[1].GetOptions().GetPageToken() != "page-2" { + t.Fatalf("paged list err = %v, reqs = %+v", err, client.listReqs) + } + out.Reset() + if err := runCreateExternalVolumeClass(ctx, client, &out, "yaml", fastSSD); err != nil || cmp.Diff(fastSSD, client.createReq.GetExternalVolumeClass(), protocmp.Transform()) != "" { + t.Fatalf("create err = %v, req = %v", err, client.createReq) + } + out.Reset() + opts := &ateapi.DeleteOptions{Uid: "u-1", Version: 3} + if err := runDeleteExternalVolumeClass(ctx, client, &out, "fast-ssd", opts); err != nil || out.String() != "external volume class \"fast-ssd\" deleted\n" { + t.Fatalf("delete err = %v, out = %q", err, out.String()) + } + if diff := cmp.Diff(&ateapi.DeleteExternalVolumeClassRequest{ExternalVolumeClass: &ateapi.ObjectRef{Name: "fast-ssd"}, Options: opts}, client.deleteReq, protocmp.Transform()); diff != "" { + t.Errorf("deleteReq mismatch (-want +got):\n%s", diff) + } + if _, _, err := runRootCLI(t, "delete", "external-volume-class", "fast-ssd", "--version", "0"); err == nil || !strings.Contains(err.Error(), "--version must be at least 1") { + t.Fatalf("delete --version 0 error = %v, want --version must be at least 1", err) + } + if _, _, err := runRootCLI(t, "delete", "external-volume-class", "fast-ssd", "--uid", ""); err == nil || !strings.Contains(err.Error(), "--uid must not be empty") { + t.Fatalf("delete --uid '' error = %v, want --uid must not be empty", err) + } +} From 5c0456a4d07af162d1888db88f54d2398a8a299e Mon Sep 17 00:00:00 2001 From: Vu Le Date: Tue, 10 Nov 2026 19:51:08 +0000 Subject: [PATCH 14/30] CLI reference documentation Signed-off-by: Vu Le --- .../cmd/external_volume_class_test.go | 63 ++++++++++++++++++- .../internal/printer/external_volume_class.go | 15 ++++- .../printer/external_volume_class_test.go | 28 +++++++++ docs/reference/kubectl-ate.md | 42 ++++++++++++- 4 files changed, 144 insertions(+), 4 deletions(-) diff --git a/cmd/kubectl-ate/internal/cmd/external_volume_class_test.go b/cmd/kubectl-ate/internal/cmd/external_volume_class_test.go index 4baece48aa..46c544c33b 100644 --- a/cmd/kubectl-ate/internal/cmd/external_volume_class_test.go +++ b/cmd/kubectl-ate/internal/cmd/external_volume_class_test.go @@ -17,6 +17,9 @@ package cmd import ( "bytes" "context" + "errors" + "os" + "path/filepath" "strings" "testing" "time" @@ -25,6 +28,7 @@ import ( "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/kubectl-ate/internal/printer" "google.golang.org/grpc" + "google.golang.org/protobuf/proto" "google.golang.org/protobuf/testing/protocmp" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -34,6 +38,8 @@ func TestExternalVolumeClassCommandArgs(t *testing.T) { {name: "list", command: getExternalVolumeClassesCmd}, {name: "get", command: getExternalVolumeClassesCmd, args: []string{"fast-ssd"}}, {name: "get multiple", command: getExternalVolumeClassesCmd, args: []string{"fast-ssd", "standard-rwo"}}, + {name: "create missing -f", command: createExternalVolumeClassCmd, wantErr: true}, + {name: "create extra arg", command: createExternalVolumeClassCmd, args: []string{"fast-ssd"}, wantErr: true}, {name: "delete", command: deleteExternalVolumeClassCmd, args: []string{"fast-ssd"}}, {name: "delete missing name", command: deleteExternalVolumeClassCmd, wantErr: true}, {name: "delete extra name", command: deleteExternalVolumeClassCmd, args: []string{"a", "b"}, wantErr: true}, @@ -95,13 +101,20 @@ type fakeExternalVolumeClassClient struct { listReqs []*ateapi.ListExternalVolumeClassesRequest createReq *ateapi.CreateExternalVolumeClassRequest deleteReq *ateapi.DeleteExternalVolumeClassRequest + err error } func (f *fakeExternalVolumeClassClient) GetExternalVolumeClass(_ context.Context, req *ateapi.GetExternalVolumeClassRequest, _ ...grpc.CallOption) (*ateapi.ExternalVolumeClass, error) { + if f.err != nil { + return nil, f.err + } return f.byName[req.GetExternalVolumeClass().GetName()], nil } func (f *fakeExternalVolumeClassClient) ListExternalVolumeClasses(_ context.Context, req *ateapi.ListExternalVolumeClassesRequest, _ ...grpc.CallOption) (*ateapi.ListExternalVolumeClassesResponse, error) { f.listReqs = append(f.listReqs, req) + if f.err != nil { + return nil, f.err + } if len(f.listPages) == 0 { return &ateapi.ListExternalVolumeClassesResponse{}, nil } @@ -111,10 +124,18 @@ func (f *fakeExternalVolumeClassClient) ListExternalVolumeClasses(_ context.Cont } func (f *fakeExternalVolumeClassClient) CreateExternalVolumeClass(_ context.Context, req *ateapi.CreateExternalVolumeClassRequest, _ ...grpc.CallOption) (*ateapi.ExternalVolumeClass, error) { f.createReq = req - return req.GetExternalVolumeClass(), nil + if f.err != nil { + return nil, f.err + } + created := proto.Clone(req.GetExternalVolumeClass()).(*ateapi.ExternalVolumeClass) + created.Metadata.Uid, created.Metadata.Version = "srv-uid-1", 7 + return created, nil } func (f *fakeExternalVolumeClassClient) DeleteExternalVolumeClass(_ context.Context, req *ateapi.DeleteExternalVolumeClassRequest, _ ...grpc.CallOption) (*ateapi.ExternalVolumeClass, error) { f.deleteReq = req + if f.err != nil { + return nil, f.err + } return &ateapi.ExternalVolumeClass{Metadata: &ateapi.ResourceMetadata{Name: req.GetExternalVolumeClass().GetName()}}, nil } @@ -146,6 +167,11 @@ func TestExternalVolumeClassRunners(t *testing.T) { if err := runCreateExternalVolumeClass(ctx, client, &out, "yaml", fastSSD); err != nil || cmp.Diff(fastSSD, client.createReq.GetExternalVolumeClass(), protocmp.Transform()) != "" { t.Fatalf("create err = %v, req = %v", err, client.createReq) } + for _, w := range []string{"uid: srv-uid-1", `version: "7"`, "driverName: pd.csi.storage.gke.io"} { + if !strings.Contains(out.String(), w) { + t.Errorf("create out = %q, want server response field %q", out.String(), w) + } + } out.Reset() opts := &ateapi.DeleteOptions{Uid: "u-1", Version: 3} if err := runDeleteExternalVolumeClass(ctx, client, &out, "fast-ssd", opts); err != nil || out.String() != "external volume class \"fast-ssd\" deleted\n" { @@ -154,6 +180,13 @@ func TestExternalVolumeClassRunners(t *testing.T) { if diff := cmp.Diff(&ateapi.DeleteExternalVolumeClassRequest{ExternalVolumeClass: &ateapi.ObjectRef{Name: "fast-ssd"}, Options: opts}, client.deleteReq, protocmp.Transform()); diff != "" { t.Errorf("deleteReq mismatch (-want +got):\n%s", diff) } + bad := filepath.Join(t.TempDir(), "evc.yaml") + if err := os.WriteFile(bad, []byte("metadata: {atespace: a, name: b}\n"), 0o600); err != nil { + t.Fatal(err) + } + if _, _, err := runRootCLI(t, "create", "external-volume-class", "-f", bad); err == nil || !strings.Contains(err.Error(), "metadata.atespace must be empty") { + t.Fatalf("create -f bad error = %v, want metadata.atespace must be empty", err) + } if _, _, err := runRootCLI(t, "delete", "external-volume-class", "fast-ssd", "--version", "0"); err == nil || !strings.Contains(err.Error(), "--version must be at least 1") { t.Fatalf("delete --version 0 error = %v, want --version must be at least 1", err) } @@ -161,3 +194,31 @@ func TestExternalVolumeClassRunners(t *testing.T) { t.Fatalf("delete --uid '' error = %v, want --uid must not be empty", err) } } + +func TestExternalVolumeClassRunnersPropagateErrors(t *testing.T) { + ctx := context.Background() + boom := errors.New("boom") + client := &fakeExternalVolumeClassClient{err: boom} + class := &ateapi.ExternalVolumeClass{Metadata: &ateapi.ResourceMetadata{Name: "x"}, DriverName: "d"} + var out bytes.Buffer + for _, tc := range []struct { + name, want string + run func() error + }{ + {"get", `failed to get external volume class "x"`, func() error { return runGetExternalVolumeClasses(ctx, client, &out, "table", []string{"x"}) }}, + {"list", "failed to list external volume classes", func() error { return runGetExternalVolumeClasses(ctx, client, &out, "table", nil) }}, + {"create", "failed to create external volume class", func() error { return runCreateExternalVolumeClass(ctx, client, &out, "yaml", class) }}, + {"delete", "failed to delete external volume class", func() error { return runDeleteExternalVolumeClass(ctx, client, &out, "x", nil) }}, + } { + t.Run(tc.name, func(t *testing.T) { + out.Reset() + err := tc.run() + if !errors.Is(err, boom) || !strings.Contains(err.Error(), tc.want) { + t.Fatalf("err = %v, want %q wrapping boom", err, tc.want) + } + if out.Len() != 0 { + t.Errorf("out = %q, want nothing printed on error", out.String()) + } + }) + } +} diff --git a/cmd/kubectl-ate/internal/printer/external_volume_class.go b/cmd/kubectl-ate/internal/printer/external_volume_class.go index 457d4413cd..4d9cb13a4e 100644 --- a/cmd/kubectl-ate/internal/printer/external_volume_class.go +++ b/cmd/kubectl-ate/internal/printer/external_volume_class.go @@ -26,6 +26,10 @@ import ( "go.ate.dev/substrate/api/ateapi/v1" ) +// maxParametersWidth caps the PARAMETERS table column, in runes. -o yaml and +// -o json print every parameter. +const maxParametersWidth = 40 + func formatParameters(params map[string]string) string { if len(params) == 0 { return "-" @@ -34,7 +38,16 @@ func formatParameters(params map[string]string) string { for i, k := range keys { keys[i] = k + "=" + params[k] } - return strings.Join(keys, ",") + return truncateColumn(strings.Join(keys, ","), maxParametersWidth) +} + +// truncateColumn shortens s to at most n runes, ending in "..." when it cuts. +func truncateColumn(s string, n int) string { + r := []rune(s) + if len(r) <= n { + return s + } + return string(r[:n-3]) + "..." } // PrintExternalVolumeClassesTo prints a slice of external volume classes to the provided writer. diff --git a/cmd/kubectl-ate/internal/printer/external_volume_class_test.go b/cmd/kubectl-ate/internal/printer/external_volume_class_test.go index 456f841efe..4514d68f28 100644 --- a/cmd/kubectl-ate/internal/printer/external_volume_class_test.go +++ b/cmd/kubectl-ate/internal/printer/external_volume_class_test.go @@ -80,3 +80,31 @@ func TestPrintExternalVolumeClasses(t *testing.T) { }) } } + +func TestPrintExternalVolumeClassTruncatesParameters(t *testing.T) { + nfs := &ateapi.ExternalVolumeClass{ + Metadata: &ateapi.ResourceMetadata{Name: "nfs"}, + DriverName: "nfs.csi.k8s.io", + Parameters: map[string]string{"server": "nfs-server.default.svc.cluster.local", "share": "/exports/team-a"}, + } + var table bytes.Buffer + if err := PrintExternalVolumeClassTo(&table, nfs, "table"); err != nil { + t.Fatal(err) + } + // "server=nfs-server.default.svc.cluster" is 37 runes; +"..." = 40. + if got := table.String(); !strings.Contains(got, "server=nfs-server.default.svc.cluster...") || strings.Contains(got, "share=") { + t.Errorf("table = %q, want PARAMETERS cut to 40 runes", got) + } + var yamlOut bytes.Buffer + if err := PrintExternalVolumeClassTo(&yamlOut, nfs, "yaml"); err != nil { + t.Fatal(err) + } + for _, w := range []string{"server: nfs-server.default.svc.cluster.local", "share: /exports/team-a"} { + if !strings.Contains(yamlOut.String(), w) { + t.Errorf("yaml = %q, want lossless %q", yamlOut.String(), w) + } + } + if got := truncateColumn("ééééé", 4); got != "é..." { + t.Errorf(`truncateColumn("ééééé", 4) = %q, want "é..."`, got) + } +} diff --git a/docs/reference/kubectl-ate.md b/docs/reference/kubectl-ate.md index 6e3e9819ca..7e13cd4a45 100644 --- a/docs/reference/kubectl-ate.md +++ b/docs/reference/kubectl-ate.md @@ -4,7 +4,7 @@ linkTitle: "CLI Reference" weight: 3 card_icon: "fa-solid fa-terminal" description: > - Manage atespaces, actor templates, actors, snapshots, egress policies, and logs with the kubectl-ate plugin. + Manage atespaces, external volume classes, actor templates, actors, snapshots, egress policies, and logs with the kubectl-ate plugin. --- # `kubectl-ate` @@ -102,7 +102,7 @@ kubectl ate top workers > **Note:** `get actors` requires either `--atespace ` / `-a ` (one atespace) or `-A`/`--all-atespaces` (all atespaces) — there is no default atespace. Getting a single actor always requires `--atespace`/`-a`, since an actor is addressed by `(atespace, name)`. `-a` (lower-case) scopes to one atespace; `-A` (upper-case) spans all. -> **Note:** Actors, workers, and actor templates are not Kubernetes CRDs — they live in the Substrate control plane's PostgreSQL database, not `etcd`. `kubectl get actor`, `kubectl get worker`, and `kubectl get actortemplate` will not return anything; only `kubectl ate get …` queries the control plane (see [Actor Templates](#actor-templates)). `kubectl get workerpool` *does* work, because pools are CRDs. +> **Note:** Actors, workers, actor templates, and external volume classes are not Kubernetes CRDs — they live in the Substrate control plane's PostgreSQL database, not `etcd`. `kubectl get actor`, `kubectl get worker`, `kubectl get actortemplate`, and `kubectl get externalvolumeclass` will not return anything; only `kubectl ate get …` queries the control plane (see [Actor Templates](#actor-templates) and [External Volume Classes](#external-volume-classes)). `kubectl get workerpool` *does* work, because pools are CRDs. #### `kubectl ate get actor` output columns @@ -157,6 +157,44 @@ kubectl ate delete atespace | `NAME` | The atespace name. Globally unique — atespaces are global-scoped. | | `AGE` | Time elapsed since the atespace was created. | +### External Volume Classes + +An **external volume class** (`ExternalVolumeClass`) is a global-scoped resource that names the CSI driver (`driverName`) and driver-specific `parameters` used to provision external volumes for actors. External volume classes are immutable. To change one, delete and recreate it. Creating an external volume class requires the `ExternalVolumes` preview gate on the server and `--preview` on the CLI. + +Example `volume-class.yaml`: + +```yaml +metadata: + name: csi-nfs +driverName: nfs.csi.k8s.io +parameters: + server: nfs-server.default.svc.cluster.local + share: / +``` + +```bash +# Create an external volume class from a manifest (protojson-shaped +# ateapi.ExternalVolumeClass, a single YAML/JSON document; use -f - for stdin). +kubectl ate create external-volume-class -f volume-class.yaml --preview + +# List all external volume classes, or get one (also: -o yaml prints the re-applyable manifest). +kubectl ate get external-volume-classes +kubectl ate get external-volume-class -o yaml + +# Delete an external volume class (optionally guarded by --uid and/or --version). +kubectl ate delete external-volume-class +kubectl ate delete external-volume-class --uid --version +``` + +#### `kubectl ate get external-volume-class` output columns + +| Column | Meaning | +|---|---| +| `NAME` | The external volume class name. Globally unique; external volume classes are global-scoped. | +| `DRIVER` | The CSI driver name (`driverName`) that provisions volumes of this class. | +| `PARAMETERS` | Comma-separated `key=value` driver parameters sorted by key, cut to 40 characters with `...`; `-o yaml` shows them all. `-` when the class defines no parameters. | +| `AGE` | Time elapsed since the external volume class was created. | + ### Actor Templates An **actor template** describes what an actor runs: containers, volumes, From ae98b2478373d9c2b60d3d73172dffc993283071 Mon Sep 17 00:00:00 2001 From: Vu Le Date: Tue, 10 Nov 2026 22:20:15 +0000 Subject: [PATCH 15/30] add proto, validation, codegen, apitool example Signed-off-by: Vu Le --- api/ateapi/v1/ateapi.pb.go | 44 ++++++++-- api/ateapi/v1/ateapi.proto | 20 +++++ .../external_volume_class_test.go | 21 +++++ .../internal/apivalidation/validation_test.go | 16 ++++ .../apivalidation/zz_generated.validation.go | 88 +++++++++++++++++++ .../examples/grpc/ExternalVolumeClass.yaml | 2 + 6 files changed, 186 insertions(+), 5 deletions(-) diff --git a/api/ateapi/v1/ateapi.pb.go b/api/ateapi/v1/ateapi.pb.go index 8c46c8a616..4cec1354b6 100644 --- a/api/ateapi/v1/ateapi.pb.go +++ b/api/ateapi/v1/ateapi.pb.go @@ -1135,6 +1135,15 @@ type ExternalVolumeStatus struct { // +k8s:optional // +k8s:customValidation # at most 40 KiB in total, ten times the CSI limit for map fields VolumeContext map[string]string `protobuf:"bytes,4,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"` + // mount_options from the volume's class, passed to the CSI driver as + // VolumeCapability.Mount.MountFlags at mount time. + // + // +k8s:optional + // +k8s:maxItems=32 + // +k8s:listType=atomic + // +k8s:eachVal=+k8s:minLength=1 + // +k8s:eachVal=+k8s:maxLength=256 + MountOptions []string `protobuf:"bytes,5,rep,name=mount_options,json=mountOptions,proto3" json:"mount_options,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1197,6 +1206,13 @@ func (x *ExternalVolumeStatus) GetVolumeContext() map[string]string { return nil } +func (x *ExternalVolumeStatus) GetMountOptions() []string { + if x != nil { + return x.MountOptions + } + return nil +} + type Actor struct { state protoimpl.MessageState `protogen:"open.v1"` // Common resource metadata: atespace, name, uid, version, timestamps. @@ -4089,7 +4105,16 @@ type ExternalVolumeClass struct { // +k8s:maxProperties=32 // +k8s:eachKey=+k8s:maxLength=128 // +k8s:eachVal=+k8s:maxLength=256 - Parameters map[string]string `protobuf:"bytes,3,rep,name=parameters,proto3" json:"parameters,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + Parameters map[string]string `protobuf:"bytes,3,rep,name=parameters,proto3" json:"parameters,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // mount_options are passed to the CSI driver as + // VolumeCapability.Mount.MountFlags at mount time. + // + // +k8s:optional + // +k8s:maxItems=32 + // +k8s:listType=atomic + // +k8s:eachVal=+k8s:minLength=1 + // +k8s:eachVal=+k8s:maxLength=256 + MountOptions []string `protobuf:"bytes,4,rep,name=mount_options,json=mountOptions,proto3" json:"mount_options,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -4145,6 +4170,13 @@ func (x *ExternalVolumeClass) GetParameters() map[string]string { return nil } +func (x *ExternalVolumeClass) GetMountOptions() []string { + if x != nil { + return x.MountOptions + } + return nil +} + // SystemInfoVolumeSource is a read-only volume of substrate-generated // per-actor files (identity fields, projected trust bundles), regenerated by // atelet on every Run/Restore. @@ -10395,13 +10427,14 @@ const file_api_ateapi_v1_ateapi_proto_rawDesc = "" + "\vdelete_time\x18\a \x01(\v2\x1a.google.protobuf.TimestampR\n" + "deleteTime\"V\n" + "\x0fExternalVolumes\x12C\n" + - "\avolumes\x18\x01 \x03(\v2).substrate.ateapi.v1.ExternalVolumeStatusR\avolumes\"\x9e\x02\n" + + "\avolumes\x18\x01 \x03(\v2).substrate.ateapi.v1.ExternalVolumeStatusR\avolumes\"\xc3\x02\n" + "\x14ExternalVolumeStatus\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12*\n" + "\x11storage_volume_id\x18\x02 \x01(\tR\x0fstorageVolumeId\x12\x1f\n" + "\vvolume_type\x18\x03 \x01(\tR\n" + "volumeType\x12c\n" + - "\x0evolume_context\x18\x04 \x03(\v2<.substrate.ateapi.v1.ExternalVolumeStatus.VolumeContextEntryR\rvolumeContext\x1a@\n" + + "\x0evolume_context\x18\x04 \x03(\v2<.substrate.ateapi.v1.ExternalVolumeStatus.VolumeContextEntryR\rvolumeContext\x12#\n" + + "\rmount_options\x18\x05 \x03(\tR\fmountOptions\x1a@\n" + "\x12VolumeContextEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\xe2\x02\n" + @@ -10559,14 +10592,15 @@ const file_api_ateapi_v1_ateapi_proto_rawDesc = "" + "\x16ExternalVolumeTemplate\x12%\n" + "\x0ecapacity_bytes\x18\x01 \x01(\x03R\rcapacityBytes\x12,\n" + "\x12storage_class_name\x18\x02 \x01(\tR\x10storageClassName\x12R\n" + - "\x15external_volume_class\x18\x03 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x13externalVolumeClass\"\xb1\x02\n" + + "\x15external_volume_class\x18\x03 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x13externalVolumeClass\"\xd6\x02\n" + "\x13ExternalVolumeClass\x12A\n" + "\bmetadata\x18\x01 \x01(\v2%.substrate.ateapi.v1.ResourceMetadataR\bmetadata\x12\x1f\n" + "\vdriver_name\x18\x02 \x01(\tR\n" + "driverName\x12X\n" + "\n" + "parameters\x18\x03 \x03(\v28.substrate.ateapi.v1.ExternalVolumeClass.ParametersEntryR\n" + - "parameters\x1a=\n" + + "parameters\x12#\n" + + "\rmount_options\x18\x04 \x03(\tR\fmountOptions\x1a=\n" + "\x0fParametersEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01:\x1d\x82\xb5\x18\x19\x18\x02\"\x15ExternalVolumeClasses\"f\n" + diff --git a/api/ateapi/v1/ateapi.proto b/api/ateapi/v1/ateapi.proto index 7a1675d07f..51511e139b 100644 --- a/api/ateapi/v1/ateapi.proto +++ b/api/ateapi/v1/ateapi.proto @@ -555,6 +555,16 @@ message ExternalVolumeStatus { // +k8s:optional // +k8s:customValidation # at most 40 KiB in total, ten times the CSI limit for map fields map volume_context = 4; + + // mount_options from the volume's class, passed to the CSI driver as + // VolumeCapability.Mount.MountFlags at mount time. + // + // +k8s:optional + // +k8s:maxItems=32 + // +k8s:listType=atomic + // +k8s:eachVal=+k8s:minLength=1 + // +k8s:eachVal=+k8s:maxLength=256 + repeated string mount_options = 5; } message Actor { @@ -1626,6 +1636,16 @@ message ExternalVolumeClass { // +k8s:eachKey=+k8s:maxLength=128 // +k8s:eachVal=+k8s:maxLength=256 map parameters = 3; + + // mount_options are passed to the CSI driver as + // VolumeCapability.Mount.MountFlags at mount time. + // + // +k8s:optional + // +k8s:maxItems=32 + // +k8s:listType=atomic + // +k8s:eachVal=+k8s:minLength=1 + // +k8s:eachVal=+k8s:maxLength=256 + repeated string mount_options = 4; } // SystemInfoVolumeSource is a read-only volume of substrate-generated diff --git a/cmd/ateapi/internal/apivalidation/external_volume_class_test.go b/cmd/ateapi/internal/apivalidation/external_volume_class_test.go index 9c023c015a..e0f883c78c 100644 --- a/cmd/ateapi/internal/apivalidation/external_volume_class_test.go +++ b/cmd/ateapi/internal/apivalidation/external_volume_class_test.go @@ -16,6 +16,7 @@ package apivalidation import ( "context" + "slices" "strings" "testing" @@ -68,6 +69,26 @@ func TestValidateCreateExternalVolumeClassRequest(t *testing.T) { mutate: func(c *ateapi.ExternalVolumeClass) { c.Parameters = map[string]string{"k": strings.Repeat("v", 257)} }, want: field.ErrorList{field.Forbidden(evc, "")}, wantWithPreview: field.ErrorList{field.TooLong(evc.Child("parameters").Key("k"), "", 256).WithOrigin("maxLength")}, + }, { + name: "valid mount_options", + mutate: func(c *ateapi.ExternalVolumeClass) { c.MountOptions = []string{"nfsvers=4.1", "noatime"} }, + want: field.ErrorList{field.Forbidden(evc, "")}, + wantWithPreview: nil, + }, { + name: "empty mount_options item", + mutate: func(c *ateapi.ExternalVolumeClass) { c.MountOptions = []string{""} }, + want: field.ErrorList{field.Forbidden(evc, "")}, + wantWithPreview: field.ErrorList{field.TooShort(evc.Child("mount_options").Index(0), "", 1).WithOrigin("minLength")}, + }, { + name: "too-long mount_options item", + mutate: func(c *ateapi.ExternalVolumeClass) { c.MountOptions = []string{strings.Repeat("a", 257)} }, + want: field.ErrorList{field.Forbidden(evc, "")}, + wantWithPreview: field.ErrorList{field.TooLong(evc.Child("mount_options").Index(0), "", 256).WithOrigin("maxLength")}, + }, { + name: "too many mount_options", + mutate: func(c *ateapi.ExternalVolumeClass) { c.MountOptions = slices.Repeat([]string{"ro"}, 33) }, + want: field.ErrorList{field.Forbidden(evc, "")}, + wantWithPreview: field.ErrorList{field.TooMany(evc.Child("mount_options"), 33, 32).WithOrigin("maxItems")}, }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/cmd/ateapi/internal/apivalidation/validation_test.go b/cmd/ateapi/internal/apivalidation/validation_test.go index 6534715a8c..2558e216eb 100644 --- a/cmd/ateapi/internal/apivalidation/validation_test.go +++ b/cmd/ateapi/internal/apivalidation/validation_test.go @@ -18,6 +18,7 @@ import ( "context" "fmt" "math" + "slices" "strings" "testing" @@ -956,6 +957,21 @@ func TestValidateExternalVolume(t *testing.T) { v.VolumeContext = map[string]string{"attachment": strings.Repeat("v", 40*1024)} }), want: field.ErrorList{field.TooLong(field.NewPath("volume_context"), nil, 40*1024)}, + }, { + name: "valid mount_options", + obj: valid(func(v *ateapi.ExternalVolumeStatus) { v.MountOptions = []string{"nfsvers=4.1", "noatime"} }), + }, { + name: "empty mount_options item", + obj: valid(func(v *ateapi.ExternalVolumeStatus) { v.MountOptions = []string{""} }), + want: field.ErrorList{field.TooShort(field.NewPath("mount_options").Index(0), "", 1).WithOrigin("minLength")}, + }, { + name: "too-long mount_options item", + obj: valid(func(v *ateapi.ExternalVolumeStatus) { v.MountOptions = []string{strings.Repeat("a", 257)} }), + want: field.ErrorList{field.TooLong(field.NewPath("mount_options").Index(0), "", 256).WithOrigin("maxLength")}, + }, { + name: "too many mount_options", + obj: valid(func(v *ateapi.ExternalVolumeStatus) { v.MountOptions = slices.Repeat([]string{"ro"}, 33) }), + want: field.ErrorList{field.TooMany(field.NewPath("mount_options"), 33, 32).WithOrigin("maxItems")}, }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/cmd/ateapi/internal/apivalidation/zz_generated.validation.go b/cmd/ateapi/internal/apivalidation/zz_generated.validation.go index 1f42e7e26a..a2b68575b5 100644 --- a/cmd/ateapi/internal/apivalidation/zz_generated.validation.go +++ b/cmd/ateapi/internal/apivalidation/zz_generated.validation.go @@ -4174,6 +4174,50 @@ func Validate_ExternalVolumeClass( errs = append(errs, fn(fldPath.Child("parameters"), obj.Parameters, oldVal, oldObj != nil)...) } + { // field v1.ExternalVolumeClass.MountOptions + 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 ateDeepEqual(obj, oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.MaxItems(ctx, op, fldPath, obj, oldObj, 32).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.EachValSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, + func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList { + return validate.MinLength(ctx, op, fldPath, obj, oldObj, 1) + }); len(e) != 0 { + errs = append(errs, e...) + } + if e := validate.EachValSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, + 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 *v1.ExternalVolumeClass) []string { + return oldObj.MountOptions + }) + errs = append(errs, fn(fldPath.Child("mount_options"), obj.MountOptions, oldVal, oldObj != nil)...) + } + return errs } @@ -4384,6 +4428,50 @@ func Validate_ExternalVolumeStatus( errs = append(errs, fn(fldPath.Child("volume_context"), obj.VolumeContext, oldVal, oldObj != nil)...) } + { // field v1.ExternalVolumeStatus.MountOptions + 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 ateDeepEqual(obj, oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.MaxItems(ctx, op, fldPath, obj, oldObj, 32).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.EachValSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, + func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList { + return validate.MinLength(ctx, op, fldPath, obj, oldObj, 1) + }); len(e) != 0 { + errs = append(errs, e...) + } + if e := validate.EachValSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, + 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 *v1.ExternalVolumeStatus) []string { + return oldObj.MountOptions + }) + errs = append(errs, fn(fldPath.Child("mount_options"), obj.MountOptions, oldVal, oldObj != nil)...) + } + return errs } diff --git a/tools/apitool/internal/examples/grpc/ExternalVolumeClass.yaml b/tools/apitool/internal/examples/grpc/ExternalVolumeClass.yaml index 1faa0d1b45..df809c49cb 100644 --- a/tools/apitool/internal/examples/grpc/ExternalVolumeClass.yaml +++ b/tools/apitool/internal/examples/grpc/ExternalVolumeClass.yaml @@ -21,3 +21,5 @@ driverName: nfs.csi.k8s.io parameters: server: nfs-server.default.svc.cluster.local share: / +mountOptions: +- nfsvers=4.1 From bf04614d7271bc4e77bf2942c76229a1f9a67071 Mon Sep 17 00:00:00 2001 From: Vu Le Date: Tue, 10 Nov 2026 22:20:40 +0000 Subject: [PATCH 16/30] add controlapi resolver and ExternalVolumeStatus wiring Signed-off-by: Vu Le --- .../controlapi/functionaltest/actor_test.go | 13 +++- cmd/ateapi/internal/controlapi/volumes.go | 35 ++++++----- .../internal/controlapi/volumes_test.go | 60 +++++++++++++------ 3 files changed, 70 insertions(+), 38 deletions(-) diff --git a/cmd/ateapi/internal/controlapi/functionaltest/actor_test.go b/cmd/ateapi/internal/controlapi/functionaltest/actor_test.go index 678063aa9d..1028f4f1d2 100644 --- a/cmd/ateapi/internal/controlapi/functionaltest/actor_test.go +++ b/cmd/ateapi/internal/controlapi/functionaltest/actor_test.go @@ -2005,9 +2005,10 @@ func TestActorLifecycle_WithExternalVolumeClass(t *testing.T) { class, err := tc.client.CreateExternalVolumeClass(ctx, &ateapi.CreateExternalVolumeClassRequest{ ExternalVolumeClass: &ateapi.ExternalVolumeClass{ - Metadata: &ateapi.ResourceMetadata{Name: "evc-gold"}, - DriverName: "substrate.io/mock", - Parameters: map[string]string{"tier": "gold"}, + Metadata: &ateapi.ResourceMetadata{Name: "evc-gold"}, + DriverName: "substrate.io/mock", + Parameters: map[string]string{"tier": "gold"}, + MountOptions: []string{"nfsvers=4.1"}, }, }) if err != nil { @@ -2041,6 +2042,9 @@ func TestActorLifecycle_WithExternalVolumeClass(t *testing.T) { if len(created) != 1 || created[0].GetVolumeType() != "substrate.io/mock" || created[0].GetStorageVolumeId() != "" { t.Fatalf("CreateActor volumes = %v, want 1 unprovisioned volume of type substrate.io/mock", created) } + if diff := cmp.Diff([]string{"nfsvers=4.1"}, created[0].GetMountOptions()); diff != "" { + t.Errorf("CreateActor mount options mismatch (-want +got):\n%s", diff) + } resumeResp, err := tc.client.ResumeActor(ctx, &ateapi.ResumeActorRequest{Actor: actorRef}) if err != nil { @@ -2053,6 +2057,9 @@ func TestActorLifecycle_WithExternalVolumeClass(t *testing.T) { if got := resumed[0].GetVolumeContext()["tier"]; got != "gold" { t.Errorf("volume context tier = %q, want %q from the class parameters", got, "gold") } + if diff := cmp.Diff([]string{"nfsvers=4.1"}, resumed[0].GetMountOptions()); diff != "" { + t.Errorf("ResumeActor mount options mismatch (-want +got):\n%s", diff) + } if _, err := tc.client.DeleteActor(ctx, &ateapi.DeleteActorRequest{Actor: actorRef}); err != nil { t.Fatalf("DeleteActor failed: %v", err) diff --git a/cmd/ateapi/internal/controlapi/volumes.go b/cmd/ateapi/internal/controlapi/volumes.go index d89424743c..f75d6736de 100644 --- a/cmd/ateapi/internal/controlapi/volumes.go +++ b/cmd/ateapi/internal/controlapi/volumes.go @@ -45,12 +45,13 @@ type externalVolumeClassGetter interface { } // volumeClass is what an external volume template resolves to: the CSI driver, -// the parameters for its CreateVolume call, and a label that names the class -// in errors. +// the parameters for its CreateVolume call, its mount options, and a label +// that names the class in errors. type volumeClass struct { - driver string - params map[string]string - label string + driver string + params map[string]string + mountOptions []string + label string } // resolveVolumeClass resolves the class of an external volume template from @@ -58,11 +59,11 @@ type volumeClass struct { // StorageClass named by storage_class_name. func resolveVolumeClass(ctx context.Context, classes externalVolumeClassGetter, scLister storagev1listers.StorageClassLister, tmpl *ateapi.ExternalVolumeTemplate) (volumeClass, error) { if ref := tmpl.GetExternalVolumeClass(); ref != nil { - driver, params, err := resolveExternalVolumeClass(ctx, classes, ref) + driver, params, mountOptions, err := resolveExternalVolumeClass(ctx, classes, ref) if err != nil { return volumeClass{}, err } - return volumeClass{driver: driver, params: params, label: fmt.Sprintf("ExternalVolumeClass %q", ref.GetName())}, nil + return volumeClass{driver: driver, params: params, mountOptions: mountOptions, label: fmt.Sprintf("ExternalVolumeClass %q", ref.GetName())}, nil } scName := tmpl.GetStorageClassName() @@ -76,22 +77,22 @@ func resolveVolumeClass(ctx context.Context, classes externalVolumeClassGetter, } return volumeClass{}, apierror.Internal("failed to get StorageClass %q: %v", scName, err) } - return volumeClass{driver: sc.Provisioner, params: sc.Parameters, label: fmt.Sprintf("StorageClass %q", scName)}, nil + return volumeClass{driver: sc.Provisioner, params: sc.Parameters, mountOptions: sc.MountOptions, label: fmt.Sprintf("StorageClass %q", scName)}, nil } -// resolveExternalVolumeClass returns the driver and CreateVolume parameters of -// the ExternalVolumeClass that ref names. A missing class is a +// resolveExternalVolumeClass returns the driver, CreateVolume parameters, and +// mount options of the ExternalVolumeClass that ref names. A missing class is a // FailedPrecondition: the template is valid, but the class it names does not // exist yet or was deleted. -func resolveExternalVolumeClass(ctx context.Context, classes externalVolumeClassGetter, ref *ateapi.ObjectRef) (driver string, params map[string]string, err error) { +func resolveExternalVolumeClass(ctx context.Context, classes externalVolumeClassGetter, ref *ateapi.ObjectRef) (driver string, params map[string]string, mountOptions []string, err error) { class, err := classes.GetExternalVolumeClass(ctx, ref.GetName()) if err != nil { if apierror.Code(err) == codes.NotFound { - return "", nil, apierror.FailedPrecondition("ExternalVolumeClass %q not found", ref.GetName()) + return "", nil, nil, apierror.FailedPrecondition("ExternalVolumeClass %q not found", ref.GetName()) } - return "", nil, apierror.Internal("failed to get ExternalVolumeClass %q: %v", ref.GetName(), err) + return "", nil, nil, apierror.Internal("failed to get ExternalVolumeClass %q: %v", ref.GetName(), err) } - return class.GetDriverName(), class.GetParameters(), nil + return class.GetDriverName(), class.GetParameters(), class.GetMountOptions(), nil } // initialExternalVolumes constructs the actor's volume objects before volume @@ -109,8 +110,9 @@ func initialExternalVolumes(ctx context.Context, classes externalVolumeClassGett } volumes = append(volumes, &ateapi.ExternalVolumeStatus{ - Name: vol.GetName(), - VolumeType: class.driver, + Name: vol.GetName(), + VolumeType: class.driver, + MountOptions: class.mountOptions, }) } } @@ -187,6 +189,7 @@ func createActorVolumes(ctx context.Context, registry VolumePluginRegistry, clas StorageVolumeId: resp.VolumeID, VolumeType: class.driver, VolumeContext: resp.VolumeContext, + MountOptions: class.mountOptions, }) } return resultVolumes, nil diff --git a/cmd/ateapi/internal/controlapi/volumes_test.go b/cmd/ateapi/internal/controlapi/volumes_test.go index 5603357dcf..0fc1e4e4e4 100644 --- a/cmd/ateapi/internal/controlapi/volumes_test.go +++ b/cmd/ateapi/internal/controlapi/volumes_test.go @@ -164,8 +164,9 @@ func TestInitialActorVolumes(t *testing.T) { VolumeType: "mock-standard", }, { - Name: "data-vol-2", - VolumeType: "mock-fast", + Name: "data-vol-2", + VolumeType: "mock-fast", + MountOptions: []string{"noatime"}, }, } @@ -176,8 +177,9 @@ func TestInitialActorVolumes(t *testing.T) { Provisioner: "mock-standard", }, "fast": { - ObjectMeta: metav1.ObjectMeta{Name: "fast"}, - Provisioner: "mock-fast", + ObjectMeta: metav1.ObjectMeta{Name: "fast"}, + Provisioner: "mock-fast", + MountOptions: []string{"noatime"}, }, }, } @@ -284,7 +286,7 @@ func TestCreateActorVolumes(t *testing.T) { }, }, { - name: "storage class parameters are propagated to volume context", + name: "storage class parameters and mount options are propagated", tmpl: standardTmpl, inputVolumes: []*ateapi.ExternalVolumeStatus{ { @@ -300,6 +302,7 @@ func TestCreateActorVolumes(t *testing.T) { "type": "pd-ssd", "csi.storage.k8s.io/fstype": "ext4", }, + MountOptions: []string{"rw", "noatime"}, }, }, wantErr: false, @@ -312,6 +315,7 @@ func TestCreateActorVolumes(t *testing.T) { "type": "pd-ssd", "csi.storage.k8s.io/fstype": "ext4", }, + MountOptions: []string{"rw", "noatime"}, }, }, }, @@ -354,19 +358,25 @@ func TestCreateActorVolumes(t *testing.T) { func TestResolveExternalVolumeClass(t *testing.T) { ref := &ateapi.ObjectRef{Name: "gold"} for _, tt := range []struct { - name string - getter *fakeExternalVolumeClassGetter - wantCode codes.Code - wantDriver string - wantParams map[string]string + name string + getter *fakeExternalVolumeClassGetter + wantCode codes.Code + wantDriver string + wantParams map[string]string + wantMountOptions []string }{{ name: "found", getter: &fakeExternalVolumeClassGetter{classes: map[string]*ateapi.ExternalVolumeClass{ - "gold": {DriverName: "mock-standard", Parameters: map[string]string{"tier": "gold"}}, + "gold": { + DriverName: "mock-standard", + Parameters: map[string]string{"tier": "gold"}, + MountOptions: []string{"nfsvers=4.1", "noatime"}, + }, }}, - wantCode: codes.OK, - wantDriver: "mock-standard", - wantParams: map[string]string{"tier": "gold"}, + wantCode: codes.OK, + wantDriver: "mock-standard", + wantParams: map[string]string{"tier": "gold"}, + wantMountOptions: []string{"nfsvers=4.1", "noatime"}, }, { name: "missing", getter: &fakeExternalVolumeClassGetter{}, @@ -377,7 +387,7 @@ func TestResolveExternalVolumeClass(t *testing.T) { wantCode: codes.Internal, }} { t.Run(tt.name, func(t *testing.T) { - driver, params, err := resolveExternalVolumeClass(context.Background(), tt.getter, ref) + driver, params, mountOptions, err := resolveExternalVolumeClass(context.Background(), tt.getter, ref) if got := apierror.Code(err); got != tt.wantCode { t.Fatalf("resolveExternalVolumeClass() code = %v, want %v; error = %v", got, tt.wantCode, err) } @@ -393,6 +403,9 @@ func TestResolveExternalVolumeClass(t *testing.T) { if diff := cmp.Diff(tt.wantParams, params); diff != "" { t.Errorf("resolveExternalVolumeClass() params mismatch (-want +got):\n%s", diff) } + if diff := cmp.Diff(tt.wantMountOptions, mountOptions); diff != "" { + t.Errorf("resolveExternalVolumeClass() mountOptions mismatch (-want +got):\n%s", diff) + } }) } } @@ -409,24 +422,32 @@ func TestActorVolumesFromExternalVolumeClass(t *testing.T) { }}, } classes := &fakeExternalVolumeClassGetter{classes: map[string]*ateapi.ExternalVolumeClass{ - "gold": {DriverName: "mock-standard", Parameters: map[string]string{"tier": "gold"}}, + "gold": { + DriverName: "mock-standard", + Parameters: map[string]string{"tier": "gold"}, + MountOptions: []string{"nfsvers=4.1"}, + }, }} registry := &mockPluginRegistry{plugins: map[string]volume.VolumePluginControlPlane{ "mock-standard": volume.NewMockVolumePlugin(), }} - t.Run("initial volume takes the class driver as its type", func(t *testing.T) { + t.Run("initial volume takes the class driver and mount options", func(t *testing.T) { got, err := initialExternalVolumes(ctx, classes, nil, tmpl) if err != nil { t.Fatalf("initialExternalVolumes() failed: %v", err) } - want := []*ateapi.ExternalVolumeStatus{{Name: "data-vol", VolumeType: "mock-standard"}} + want := []*ateapi.ExternalVolumeStatus{{ + Name: "data-vol", + VolumeType: "mock-standard", + MountOptions: []string{"nfsvers=4.1"}, + }} if diff := cmp.Diff(want, got, protocmp.Transform()); diff != "" { t.Errorf("initialExternalVolumes() mismatch (-want +got):\n%s", diff) } }) - t.Run("create passes the class parameters to the driver", func(t *testing.T) { + t.Run("create passes the class parameters and mount options", func(t *testing.T) { input := []*ateapi.ExternalVolumeStatus{{Name: "data-vol", VolumeType: "mock-standard"}} got, err := createActorVolumes(ctx, registry, classes, nil, "actor-uid-123", tmpl, input) if err != nil { @@ -437,6 +458,7 @@ func TestActorVolumesFromExternalVolumeClass(t *testing.T) { StorageVolumeId: "mock-vol-substrate-actor-uid-123-data-vol", VolumeType: "mock-standard", VolumeContext: map[string]string{"tier": "gold"}, + MountOptions: []string{"nfsvers=4.1"}, }} if diff := cmp.Diff(want, got, protocmp.Transform()); diff != "" { t.Errorf("createActorVolumes() mismatch (-want +got):\n%s", diff) From 375d7e7c77b5806a4a1dde1460dc74ea1800ead9 Mon Sep 17 00:00:00 2001 From: Vu Le Date: Tue, 10 Nov 2026 22:21:16 +0000 Subject: [PATCH 17/30] add runtime path: ateletpb, workload_spec, atelet, and CSI MountFlags Signed-off-by: Vu Le --- .../internal/controlapi/workload_spec.go | 3 ++ .../internal/controlapi/workload_spec_test.go | 13 ++++- .../internal/apivalidation/validation_test.go | 24 +++++++++ .../apivalidation/zz_generated.validation.go | 44 +++++++++++++++++ cmd/atelet/volumes.go | 1 + cmd/atelet/volumes_test.go | 49 ++++++++++++++++--- internal/proto/ateletpb/atelet.pb.go | 25 ++++++++-- internal/proto/ateletpb/atelet.proto | 10 ++++ internal/volume/csi/plugin.go | 10 +++- internal/volume/csi/plugin_test.go | 33 +++++++++++++ internal/volume/plugin.go | 3 ++ 11 files changed, 202 insertions(+), 13 deletions(-) diff --git a/cmd/ateapi/internal/controlapi/workload_spec.go b/cmd/ateapi/internal/controlapi/workload_spec.go index 57e1e5986d..eff4e92d7f 100644 --- a/cmd/ateapi/internal/controlapi/workload_spec.go +++ b/cmd/ateapi/internal/controlapi/workload_spec.go @@ -150,11 +150,13 @@ func appendExternalVolumes(workloadSpec *ateletpb.WorkloadSpec, template *ateapi var storageVolID string var volType string var volCtx map[string]string + var mountOptions []string for _, dbVol := range actor.GetStatus().GetExternalVolumes().GetVolumes() { if dbVol.GetName() == vol.GetName() { storageVolID = dbVol.GetStorageVolumeId() volType = dbVol.GetVolumeType() volCtx = dbVol.GetVolumeContext() + mountOptions = dbVol.GetMountOptions() break } } @@ -168,6 +170,7 @@ func appendExternalVolumes(workloadSpec *ateletpb.WorkloadSpec, template *ateapi VolumeType: volType, VolumeContext: volCtx, PublishContext: volumePublishContexts[vol.GetName()], + MountOptions: mountOptions, }, }) } diff --git a/cmd/ateapi/internal/controlapi/workload_spec_test.go b/cmd/ateapi/internal/controlapi/workload_spec_test.go index 69f67c82fd..9b69df2e9d 100644 --- a/cmd/ateapi/internal/controlapi/workload_spec_test.go +++ b/cmd/ateapi/internal/controlapi/workload_spec_test.go @@ -20,6 +20,7 @@ import ( "github.com/google/go-cmp/cmp" "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/proto/ateletpb" + "google.golang.org/protobuf/proto" "google.golang.org/protobuf/testing/protocmp" ) @@ -426,8 +427,10 @@ func TestAppendExternalVolumes(t *testing.T) { for _, tt := range []struct { name string + mountOptions []string volumePublishContexts map[string]map[string]string wantPublishCtx map[string]string + wantMountOptions []string }{ { name: "with attachment metadata", @@ -437,10 +440,17 @@ func TestAppendExternalVolumes(t *testing.T) { { name: "without attachment metadata", }, + { + name: "with mount options", + mountOptions: []string{"nfsvers=4.1", "noatime"}, + wantMountOptions: []string{"nfsvers=4.1", "noatime"}, + }, } { t.Run(tt.name, func(t *testing.T) { + testActor := proto.Clone(actor).(*ateapi.Actor) + testActor.Status.ExternalVolumes.Volumes[0].MountOptions = tt.mountOptions workloadSpec := &ateletpb.WorkloadSpec{} - if err := appendExternalVolumes(workloadSpec, template, actor, tt.volumePublishContexts); err != nil { + if err := appendExternalVolumes(workloadSpec, template, testActor, tt.volumePublishContexts); err != nil { t.Fatalf("appendExternalVolumes unexpected error: %v", err) } @@ -453,6 +463,7 @@ func TestAppendExternalVolumes(t *testing.T) { VolumeType: "pd-standard", VolumeContext: map[string]string{"foo": "bar"}, PublishContext: tt.wantPublishCtx, + MountOptions: tt.wantMountOptions, }, }, }, diff --git a/cmd/atelet/internal/apivalidation/validation_test.go b/cmd/atelet/internal/apivalidation/validation_test.go index 03f47b3acf..6bb566e6ce 100644 --- a/cmd/atelet/internal/apivalidation/validation_test.go +++ b/cmd/atelet/internal/apivalidation/validation_test.go @@ -17,6 +17,7 @@ package apivalidation import ( "context" "fmt" + "slices" "strings" "testing" @@ -1485,6 +1486,29 @@ func TestValidateVolume(t *testing.T) { e.PublishContext = map[string]string{"a": strings.Repeat("v", 20*1024), "b": strings.Repeat("v", 20*1024)} }), want: field.ErrorList{field.TooLong(extPath.Child("publish_context"), nil, 40*1024)}, + }, { + name: "external: valid mount_options", + obj: external(func(e *ateletpb.ExternalVolumeSource) { + e.MountOptions = []string{"nfsvers=4.1", "noatime"} + }), + }, { + name: "external: empty mount_options item", + obj: external(func(e *ateletpb.ExternalVolumeSource) { + e.MountOptions = []string{""} + }), + want: field.ErrorList{field.TooShort(extPath.Child("mount_options").Index(0), "", 1).WithOrigin("minLength")}, + }, { + name: "external: too-long mount_options item", + obj: external(func(e *ateletpb.ExternalVolumeSource) { + e.MountOptions = []string{strings.Repeat("a", 257)} + }), + want: field.ErrorList{field.TooLong(extPath.Child("mount_options").Index(0), "", 256).WithOrigin("maxLength")}, + }, { + name: "external: too many mount_options", + obj: external(func(e *ateletpb.ExternalVolumeSource) { + e.MountOptions = slices.Repeat([]string{"ro"}, 33) + }), + want: field.ErrorList{field.TooMany(extPath.Child("mount_options"), 33, 32).WithOrigin("maxItems")}, }, // ImageVolumeSource. diff --git a/cmd/atelet/internal/apivalidation/zz_generated.validation.go b/cmd/atelet/internal/apivalidation/zz_generated.validation.go index f315f19709..32aea82c8c 100644 --- a/cmd/atelet/internal/apivalidation/zz_generated.validation.go +++ b/cmd/atelet/internal/apivalidation/zz_generated.validation.go @@ -1407,6 +1407,50 @@ func Validate_ExternalVolumeSource( errs = append(errs, fn(fldPath.Child("publish_context"), obj.PublishContext, oldVal, oldObj != nil)...) } + { // field ateletpb.ExternalVolumeSource.MountOptions + 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 ateDeepEqual(obj, oldObj) { + return nil + } + } + // call field-attached validations + earlyReturn := false + if e := validate.MaxItems(ctx, op, fldPath, obj, oldObj, 32).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.EachValSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, + func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList { + return validate.MinLength(ctx, op, fldPath, obj, oldObj, 1) + }); len(e) != 0 { + errs = append(errs, e...) + } + if e := validate.EachValSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, + 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 *ateletpb.ExternalVolumeSource) []string { + return oldObj.MountOptions + }) + errs = append(errs, fn(fldPath.Child("mount_options"), obj.MountOptions, oldVal, oldObj != nil)...) + } + return errs } diff --git a/cmd/atelet/volumes.go b/cmd/atelet/volumes.go index eb34d769e8..5041f2cc4a 100644 --- a/cmd/atelet/volumes.go +++ b/cmd/atelet/volumes.go @@ -54,6 +54,7 @@ func (s *Atelet) mountExternalVolumes(ctx context.Context, actorUID string, volu TargetPath: hostPath, VolumeContext: ext.GetVolumeContext(), PublishContext: ext.GetPublishContext(), + MountOptions: ext.GetMountOptions(), }); err != nil { return fmt.Errorf("failed to mount volume %q to %q: %w", ext.GetStorageVolumeId(), hostPath, err) } diff --git a/cmd/atelet/volumes_test.go b/cmd/atelet/volumes_test.go index 060be7e3ad..e4933a1ee6 100644 --- a/cmd/atelet/volumes_test.go +++ b/cmd/atelet/volumes_test.go @@ -34,9 +34,10 @@ import ( ) type mountCall struct { - volumeID string - targetPath string - attributes map[string]string + volumeID string + targetPath string + attributes map[string]string + mountOptions []string } type fakeWorkerPlugin struct { @@ -50,9 +51,10 @@ type fakeWorkerPlugin struct { func (f *fakeWorkerPlugin) MountVolume(ctx context.Context, req volume.MountVolumeRequest) error { f.mountCalls = append(f.mountCalls, mountCall{ - volumeID: req.VolumeID, - targetPath: req.TargetPath, - attributes: req.VolumeContext, + volumeID: req.VolumeID, + targetPath: req.TargetPath, + attributes: req.VolumeContext, + mountOptions: req.MountOptions, }) if f.mountErrs != nil { if err, ok := f.mountErrs[req.VolumeID]; ok { @@ -361,6 +363,41 @@ func TestMountExternalVolumes(t *testing.T) { t.Errorf("stat vol-2 mount path %q: %v", expectedPath2, err) } }) + + t.Run("forwards mount options to plugin", func(t *testing.T) { + useTempNodeDirs(t) + + volWithOpts := &ateletpb.Volume{ + Name: "vol-opts", + External: &ateletpb.ExternalVolumeSource{ + StorageVolumeId: "mock-vol-opts", + VolumeType: "mock-driver", + MountOptions: []string{"nfsvers=4.1", "noatime"}, + }, + } + + fake := &fakeWorkerPlugin{} + s := &Atelet{ + volumePlugins: map[string]volume.VolumePluginWorkerPlane{ + "mock-driver": fake, + }, + } + + if err := s.mountExternalVolumes(ctx, actorUID, []*ateletpb.Volume{volWithOpts}); err != nil { + t.Fatalf("mountExternalVolumes failed: %v", err) + } + + wantCalls := []mountCall{ + { + volumeID: "mock-vol-opts", + targetPath: ateletpath.ExternalVolumeHostPath(actorUID, "vol-opts"), + mountOptions: []string{"nfsvers=4.1", "noatime"}, + }, + } + if diff := cmp.Diff(wantCalls, fake.mountCalls, cmp.AllowUnexported(mountCall{})); diff != "" { + t.Errorf("mountCalls mismatch (-want +got):\n%s", diff) + } + }) } func TestVolumeHostDirectoryCleanup(t *testing.T) { diff --git a/internal/proto/ateletpb/atelet.pb.go b/internal/proto/ateletpb/atelet.pb.go index 1a88aec7f5..49eb4a445e 100644 --- a/internal/proto/ateletpb/atelet.pb.go +++ b/internal/proto/ateletpb/atelet.pb.go @@ -2352,8 +2352,17 @@ type ExternalVolumeSource struct { // +k8s:optional // +k8s:customValidation # at most 40 KiB in total, ten times the CSI limit for map fields PublishContext map[string]string `protobuf:"bytes,4,rep,name=publish_context,json=publishContext,proto3" json:"publish_context,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // mount_options from the volume's class, passed to the CSI driver as + // VolumeCapability.Mount.MountFlags at mount time. + // + // +k8s:optional + // +k8s:maxItems=32 + // +k8s:listType=atomic + // +k8s:eachVal=+k8s:minLength=1 + // +k8s:eachVal=+k8s:maxLength=256 + MountOptions []string `protobuf:"bytes,5,rep,name=mount_options,json=mountOptions,proto3" json:"mount_options,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *ExternalVolumeSource) Reset() { @@ -2414,6 +2423,13 @@ func (x *ExternalVolumeSource) GetPublishContext() map[string]string { return nil } +func (x *ExternalVolumeSource) GetMountOptions() []string { + if x != nil { + return x.MountOptions + } + return nil +} + type ImageVolumeSource struct { state protoimpl.MessageState `protogen:"open.v1"` // reference is the OCI image reference, pinned by digest. @@ -4543,13 +4559,14 @@ const file_internal_proto_ateletpb_atelet_proto_rawDesc = "" + "containers\x18\x01 \x03(\v2\x11.atelet.ContainerR\n" + "containers\x12(\n" + "\avolumes\x18\x02 \x03(\v2\x0e.atelet.VolumeR\avolumes\"\x18\n" + - "\x16DurableDirVolumeSource\"\x9b\x03\n" + + "\x16DurableDirVolumeSource\"\xc0\x03\n" + "\x14ExternalVolumeSource\x12*\n" + "\x11storage_volume_id\x18\x01 \x01(\tR\x0fstorageVolumeId\x12\x1f\n" + "\vvolume_type\x18\x02 \x01(\tR\n" + "volumeType\x12V\n" + "\x0evolume_context\x18\x03 \x03(\v2/.atelet.ExternalVolumeSource.VolumeContextEntryR\rvolumeContext\x12Y\n" + - "\x0fpublish_context\x18\x04 \x03(\v20.atelet.ExternalVolumeSource.PublishContextEntryR\x0epublishContext\x1a@\n" + + "\x0fpublish_context\x18\x04 \x03(\v20.atelet.ExternalVolumeSource.PublishContextEntryR\x0epublishContext\x12#\n" + + "\rmount_options\x18\x05 \x03(\tR\fmountOptions\x1a@\n" + "\x12VolumeContextEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\x1aA\n" + diff --git a/internal/proto/ateletpb/atelet.proto b/internal/proto/ateletpb/atelet.proto index 536604385e..5ceb8f5e3a 100644 --- a/internal/proto/ateletpb/atelet.proto +++ b/internal/proto/ateletpb/atelet.proto @@ -660,6 +660,16 @@ message ExternalVolumeSource { // +k8s:optional // +k8s:customValidation # at most 40 KiB in total, ten times the CSI limit for map fields map publish_context = 4; + + // mount_options from the volume's class, passed to the CSI driver as + // VolumeCapability.Mount.MountFlags at mount time. + // + // +k8s:optional + // +k8s:maxItems=32 + // +k8s:listType=atomic + // +k8s:eachVal=+k8s:minLength=1 + // +k8s:eachVal=+k8s:maxLength=256 + repeated string mount_options = 5; } message ImageVolumeSource { diff --git a/internal/volume/csi/plugin.go b/internal/volume/csi/plugin.go index 39a17207fb..9abf9f2546 100644 --- a/internal/volume/csi/plugin.go +++ b/internal/volume/csi/plugin.go @@ -263,11 +263,14 @@ func (p *Plugin) MountVolume(ctx context.Context, req volume.MountVolumeRequest) return err } + publishCap := getStandardCapabilities()[0] + publishCap.GetMount().MountFlags = req.MountOptions + csiReq := &csi.NodePublishVolumeRequest{ VolumeId: req.VolumeID, StagingTargetPath: stagingPath, TargetPath: req.TargetPath, - VolumeCapability: getStandardCapabilities()[0], + VolumeCapability: publishCap, Readonly: false, VolumeContext: req.VolumeContext, PublishContext: req.PublishContext, @@ -291,10 +294,13 @@ func (p *Plugin) stageVolume(ctx context.Context, req volume.MountVolumeRequest) return "", fmt.Errorf("failed to create staging directory %q: %w", stagingPath, err) } + stageCap := getStandardCapabilities()[0] + stageCap.GetMount().MountFlags = req.MountOptions + csiReq := &csi.NodeStageVolumeRequest{ VolumeId: req.VolumeID, StagingTargetPath: stagingPath, - VolumeCapability: getStandardCapabilities()[0], // Use primary capability + VolumeCapability: stageCap, VolumeContext: req.VolumeContext, PublishContext: req.PublishContext, } diff --git a/internal/volume/csi/plugin_test.go b/internal/volume/csi/plugin_test.go index 9e9ad33916..4e38ba1206 100644 --- a/internal/volume/csi/plugin_test.go +++ b/internal/volume/csi/plugin_test.go @@ -389,6 +389,17 @@ func TestPlugin_MountVolume(t *testing.T) { ctx := context.Background() plugin.InitNodeCapabilities(ctx) + + var gotStageFlags, gotPublishFlags []string + driver.nodeStageVolumeFunc = func(ctx context.Context, req *csi.NodeStageVolumeRequest) (*csi.NodeStageVolumeResponse, error) { + gotStageFlags = req.GetVolumeCapability().GetMount().GetMountFlags() + return &csi.NodeStageVolumeResponse{}, nil + } + driver.nodePublishVolumeFunc = func(ctx context.Context, req *csi.NodePublishVolumeRequest) (*csi.NodePublishVolumeResponse, error) { + gotPublishFlags = req.GetVolumeCapability().GetMount().GetMountFlags() + return &csi.NodePublishVolumeResponse{}, nil + } + err = plugin.MountVolume(ctx, volume.MountVolumeRequest{ VolumeID: "test-vol", TargetPath: targetPath, @@ -397,6 +408,28 @@ func TestPlugin_MountVolume(t *testing.T) { if err != nil { t.Fatalf("MountVolume failed: %v", err) } + if len(gotStageFlags) != 0 { + t.Errorf("NodeStageVolume MountFlags = %v, want empty", gotStageFlags) + } + if len(gotPublishFlags) != 0 { + t.Errorf("NodePublishVolume MountFlags = %v, want empty", gotPublishFlags) + } + + wantMountOptions := []string{"nfsvers=4.1", "noatime"} + err = plugin.MountVolume(ctx, volume.MountVolumeRequest{ + VolumeID: "test-vol", + TargetPath: targetPath, + MountOptions: wantMountOptions, + }) + if err != nil { + t.Fatalf("MountVolume with MountOptions failed: %v", err) + } + if diff := cmp.Diff(wantMountOptions, gotStageFlags); diff != "" { + t.Errorf("NodeStageVolume MountFlags mismatch (-want +got):\n%s", diff) + } + if diff := cmp.Diff(wantMountOptions, gotPublishFlags); diff != "" { + t.Errorf("NodePublishVolume MountFlags mismatch (-want +got):\n%s", diff) + } // Verify staging directory was created stagingPath := filepath.Join(plugin.stagingDirPrefix, "test-vol") diff --git a/internal/volume/plugin.go b/internal/volume/plugin.go index c2a44991fe..f5d980c7ed 100644 --- a/internal/volume/plugin.go +++ b/internal/volume/plugin.go @@ -65,6 +65,9 @@ type MountVolumeRequest struct { // PublishContext is the metadata returned when the volume was attached to // this node. It is empty for drivers that do not implement attachment. PublishContext map[string]string + // MountOptions are passed to the CSI driver as MountFlags in the + // VolumeCapability. + MountOptions []string } // VolumePluginControlPlane abstracts storage operations performed on the control plane. From 2448c292e278425d98adada34f982f4f6150d627 Mon Sep 17 00:00:00 2001 From: Vu Le Date: Wed, 11 Nov 2026 00:04:05 +0000 Subject: [PATCH 18/30] canonical evc manifests and ate-setup registration Signed-off-by: Vu Le --- cmd/ate-setup/commands.md | 4 + cmd/ate-setup/internal/cmd/setup.go | 13 +- cmd/ate-setup/internal/steps/deploy.go | 3 + cmd/ate-setup/internal/steps/substrate.go | 139 +++++++- .../internal/steps/substrate_test.go | 326 ++++++++++++++++++ hack/csi/external-volume-class-hostpath.yaml | 18 + hack/csi/external-volume-class-nfs.yaml | 23 ++ 7 files changed, 516 insertions(+), 10 deletions(-) create mode 100644 hack/csi/external-volume-class-hostpath.yaml create mode 100644 hack/csi/external-volume-class-nfs.yaml diff --git a/cmd/ate-setup/commands.md b/cmd/ate-setup/commands.md index 0b91ed1390..d019f09119 100644 --- a/cmd/ate-setup/commands.md +++ b/cmd/ate-setup/commands.md @@ -173,6 +173,10 @@ Individual secrets and config that `deploy ate-system` creates automatically. `driver` is one of `nfs`, `hostpath`, `both`, or `none`, and defaults to `nfs`. The hostpath is for KIND clusters only. NFS has no such restriction, but it does need the `nfsd` kernel module loaded on the nodes. +When `ate-api-server` is deployed and `--preview=ExternalVolumes` (or `ATE_PREVIEW`) is set +for this command, `setup csi` also registers the matching `ExternalVolumeClass` (`csi-nfs`, +`csi-hostpath`). Run it after `deploy ate-system`, or pass `--setup-csi` to `deploy ate-system`. + ## Benchmarks diff --git a/cmd/ate-setup/internal/cmd/setup.go b/cmd/ate-setup/internal/cmd/setup.go index 43880987d8..125c8d8e26 100644 --- a/cmd/ate-setup/internal/cmd/setup.go +++ b/cmd/ate-setup/internal/cmd/setup.go @@ -34,7 +34,12 @@ Driver options: nfs (default), hostpath, both, none. Note that hostpath is single-node Kind only, while NFS is not restricted to Kind. Both drivers expose their controllers over TCP so atelet and ateapi can reach them. Re-running this removes -the previous deployment first, which clears stale mounts left behind by an earlier install.`, +the previous deployment first, which clears stale mounts left behind by an earlier install. + +When ate-api-server is deployed and --preview=ExternalVolumes (or ATE_PREVIEW) is set +for this command, this also registers the matching ExternalVolumeClass (csi-nfs, +csi-hostpath). Run "setup csi" after "deploy ate-system", or pass --setup-csi to +"deploy ate-system", so the classes are created.`, // Rejecting an unknown driver here rather than in the step means it costs // nothing: cobra validates arguments before the root command loads the // configuration and connects to a cluster. @@ -45,7 +50,11 @@ the previous deployment first, which clears stale mounts left behind by an earli return steps.ValidateCSIDriver(csiDriver(args)) }, RunE: func(cmd *cobra.Command, args []string) error { - return env.SetupCSI(cmd.Context(), csiDriver(args)) + driver := csiDriver(args) + if err := env.SetupCSI(cmd.Context(), driver); err != nil { + return err + } + return env.RegisterExternalVolumeClasses(cmd.Context(), driver) }, } diff --git a/cmd/ate-setup/internal/steps/deploy.go b/cmd/ate-setup/internal/steps/deploy.go index b1f9c4fe7a..2f4ddc6802 100644 --- a/cmd/ate-setup/internal/steps/deploy.go +++ b/cmd/ate-setup/internal/steps/deploy.go @@ -212,6 +212,9 @@ func (e *Env) DeployAteSystem(ctx context.Context, opts DeployOptions) error { return err } } + if err := e.RegisterExternalVolumeClasses(ctx, opts.SetupCSI); err != nil { + return err + } if err := e.waitFakeWorkersync(ctx); err != nil { return err } diff --git a/cmd/ate-setup/internal/steps/substrate.go b/cmd/ate-setup/internal/steps/substrate.go index 4490a71d43..75f92b0e15 100644 --- a/cmd/ate-setup/internal/steps/substrate.go +++ b/cmd/ate-setup/internal/steps/substrate.go @@ -17,15 +17,20 @@ package steps import ( "context" "fmt" + "maps" + "os" + "slices" "time" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/proto" "sigs.k8s.io/yaml" "go.ate.dev/substrate/api/ateapi/v1" + "go.ate.dev/substrate/cmd/ate-setup/internal/config" "go.ate.dev/substrate/cmd/ate-setup/internal/log" "go.ate.dev/substrate/internal/ateclient" "go.ate.dev/substrate/internal/preview" @@ -56,25 +61,143 @@ func EnsureAtespace(ctx context.Context, client *ateclient.Client, atespace stri return err } -// ActorTemplateFromManifest parses a single protojson-shaped YAML or JSON -// document into an ActorTemplate, as `kubectl ate create actor-template` -// does. Parsing is strict: unknown fields are an error, so typos don't -// silently drop configuration. -func ActorTemplateFromManifest(manifest []byte) (*ateapi.ActorTemplate, error) { +// unmarshalProtoManifest parses a single protojson-shaped YAML or JSON +// document into dst. Parsing is strict so typos fail instead of being dropped. +func unmarshalProtoManifest(manifest []byte, dst proto.Message) error { jsonData, err := yaml.YAMLToJSON(manifest) if err != nil { - return nil, fmt.Errorf("invalid YAML: %w", err) + return fmt.Errorf("invalid YAML: %w", err) } if string(jsonData) == "null" { - return nil, fmt.Errorf("manifest is empty") + return fmt.Errorf("manifest is empty") } + return protojson.Unmarshal(jsonData, dst) +} + +// ActorTemplateFromManifest parses a single protojson-shaped YAML or JSON +// document into an ActorTemplate, as `kubectl ate create actor-template` +// does. Parsing is strict: unknown fields are an error, so typos don't +// silently drop configuration. +func ActorTemplateFromManifest(manifest []byte) (*ateapi.ActorTemplate, error) { template := &ateapi.ActorTemplate{} - if err := protojson.Unmarshal(jsonData, template); err != nil { + if err := unmarshalProtoManifest(manifest, template); err != nil { return nil, err } return template, nil } +// ExternalVolumeClassFromManifest parses a single protojson-shaped YAML or +// JSON document into an ExternalVolumeClass, as `kubectl ate create +// external-volume-class` does. +func ExternalVolumeClassFromManifest(manifest []byte) (*ateapi.ExternalVolumeClass, error) { + class := &ateapi.ExternalVolumeClass{} + if err := unmarshalProtoManifest(manifest, class); err != nil { + return nil, err + } + return class, nil +} + +type externalVolumeClassClient interface { + CreateExternalVolumeClass(ctx context.Context, in *ateapi.CreateExternalVolumeClassRequest, opts ...grpc.CallOption) (*ateapi.ExternalVolumeClass, error) + GetExternalVolumeClass(ctx context.Context, in *ateapi.GetExternalVolumeClassRequest, opts ...grpc.CallOption) (*ateapi.ExternalVolumeClass, error) +} + +// RegisterExternalVolumeClasses creates the canonical ExternalVolumeClass +// resources for the selected CSI driver when the ExternalVolumes preview gate +// is enabled and ate-api-server is deployed. Existing classes with the same +// spec are kept; differing specs return an error. +func (e *Env) RegisterExternalVolumeClasses(ctx context.Context, driver string) error { + if err := ValidateCSIDriver(driver); err != nil { + return err + } + spec := csiDrivers[driver] + if spec.installsNothing() { + return nil + } + if !previewGateEnabled(e.Cfg.PreviewGates, preview.GateExternalVolumes) { + log.Infof("Skipping ExternalVolumeClass registration: %s preview gate is disabled.", preview.GateExternalVolumes) + return nil + } + classes, err := externalVolumeClassesForDriver(e.Cfg, spec) + if err != nil { + return err + } + present, err := e.Kube.DeploymentExists(ctx, e.Namespace(), "ate-api-server") + if err != nil { + return err + } + if !present { + log.Step("ate-api-server not found; skipping ExternalVolumeClass registration") + return nil + } + + client, err := e.AteClient(ctx) + if err != nil { + return err + } + defer client.Close() + + return registerExternalVolumeClasses(ctx, client, classes) +} + +func externalVolumeClassesForDriver(cfg *config.Config, spec csiDriverSpec) ([]*ateapi.ExternalVolumeClass, error) { + var paths []string + if spec.hostpath { + paths = append(paths, cfg.Path("hack", "csi", "external-volume-class-hostpath.yaml")) + } + if spec.nfs { + paths = append(paths, cfg.Path("hack", "csi", "external-volume-class-nfs.yaml")) + } + classes := make([]*ateapi.ExternalVolumeClass, 0, len(paths)) + for _, p := range paths { + data, err := os.ReadFile(p) + if err != nil { + return nil, fmt.Errorf("reading external volume class manifest %s: %w", p, err) + } + class, err := ExternalVolumeClassFromManifest(data) + if err != nil { + return nil, fmt.Errorf("parsing external volume class manifest %s: %w", p, err) + } + classes = append(classes, class) + } + return classes, nil +} + +func registerExternalVolumeClasses(ctx context.Context, client externalVolumeClassClient, classes []*ateapi.ExternalVolumeClass) error { + for _, class := range classes { + name := class.GetMetadata().GetName() + _, err := client.CreateExternalVolumeClass(ctx, &ateapi.CreateExternalVolumeClassRequest{ExternalVolumeClass: class}) + if err == nil { + log.Stepf("registered external volume class %q", name) + continue + } + if status.Code(err) != codes.AlreadyExists { + return fmt.Errorf("creating external volume class %q: %w", name, err) + } + existing, getErr := client.GetExternalVolumeClass(ctx, &ateapi.GetExternalVolumeClassRequest{ + ExternalVolumeClass: &ateapi.ObjectRef{Name: name}, + }) + if getErr != nil { + return fmt.Errorf("getting existing external volume class %q: %w", name, getErr) + } + if !externalVolumeClassEqual(class, existing) { + return fmt.Errorf("external volume class %q already exists with a different spec (got driver=%q parameters=%v mountOptions=%v, want driver=%q parameters=%v mountOptions=%v); delete and recreate it", + name, + existing.GetDriverName(), existing.GetParameters(), existing.GetMountOptions(), + class.GetDriverName(), class.GetParameters(), class.GetMountOptions()) + } + log.Stepf("external volume class %q already exists; keeping it", name) + } + return nil +} + +func externalVolumeClassEqual(want, got *ateapi.ExternalVolumeClass) bool { + return want.GetMetadata().GetName() == got.GetMetadata().GetName() && + want.GetDriverName() == got.GetDriverName() && + maps.Equal(want.GetParameters(), got.GetParameters()) && + slices.Equal(want.GetMountOptions(), got.GetMountOptions()) +} + // CreateActorTemplate creates the template through the ate API. Actor // templates are immutable (no update RPC), so an existing template is left // in place: delete the demo and redeploy to change it. diff --git a/cmd/ate-setup/internal/steps/substrate_test.go b/cmd/ate-setup/internal/steps/substrate_test.go index 19e662b873..503e584a6f 100644 --- a/cmd/ate-setup/internal/steps/substrate_test.go +++ b/cmd/ate-setup/internal/steps/substrate_test.go @@ -291,3 +291,329 @@ func TestCreateActorEgressPolicy(t *testing.T) { } }) } + +func TestExternalVolumeClassFromManifest(t *testing.T) { + root, err := config.RepoRoot() + if err != nil { + t.Fatalf("RepoRoot() = %v", err) + } + + t.Run("checked-in manifests", func(t *testing.T) { + nfsRaw, err := os.ReadFile(filepath.Join(root, "hack/csi/external-volume-class-nfs.yaml")) + if err != nil { + t.Fatalf("read nfs manifest: %v", err) + } + nfsClass, err := ExternalVolumeClassFromManifest(nfsRaw) + if err != nil { + t.Fatalf("ExternalVolumeClassFromManifest(nfs) = %v", err) + } + if nfsClass.GetMetadata().GetName() != "csi-nfs" { + t.Errorf("nfs metadata.name = %q, want %q", nfsClass.GetMetadata().GetName(), "csi-nfs") + } + if nfsClass.GetDriverName() != "nfs.csi.k8s.io" { + t.Errorf("nfs driverName = %q, want %q", nfsClass.GetDriverName(), "nfs.csi.k8s.io") + } + wantParams := map[string]string{ + "server": "nfs-server.default.svc.cluster.local", + "share": "/", + } + if got := nfsClass.GetParameters(); len(got) != len(wantParams) || got["server"] != wantParams["server"] || got["share"] != wantParams["share"] { + t.Errorf("nfs parameters = %v, want %v", got, wantParams) + } + if got := nfsClass.GetMountOptions(); len(got) != 1 || got[0] != "nfsvers=4.1" { + t.Errorf("nfs mountOptions = %v, want [nfsvers=4.1]", got) + } + + hpRaw, err := os.ReadFile(filepath.Join(root, "hack/csi/external-volume-class-hostpath.yaml")) + if err != nil { + t.Fatalf("read hostpath manifest: %v", err) + } + hpClass, err := ExternalVolumeClassFromManifest(hpRaw) + if err != nil { + t.Fatalf("ExternalVolumeClassFromManifest(hostpath) = %v", err) + } + if hpClass.GetMetadata().GetName() != "csi-hostpath" { + t.Errorf("hostpath metadata.name = %q, want %q", hpClass.GetMetadata().GetName(), "csi-hostpath") + } + if hpClass.GetDriverName() != "hostpath.csi.k8s.io" { + t.Errorf("hostpath driverName = %q, want %q", hpClass.GetDriverName(), "hostpath.csi.k8s.io") + } + if len(hpClass.GetParameters()) != 0 { + t.Errorf("hostpath parameters = %v, want empty", hpClass.GetParameters()) + } + if len(hpClass.GetMountOptions()) != 0 { + t.Errorf("hostpath mountOptions = %v, want empty", hpClass.GetMountOptions()) + } + }) + + errCases := []struct { + name string + raw string + }{ + {name: "empty", raw: ""}, + {name: "invalid yaml", raw: ":\n - [unclosed"}, + {name: "unknown field", raw: "metadata:\n name: csi-nfs\nunknownField: value\n"}, + } + for _, tc := range errCases { + t.Run(tc.name, func(t *testing.T) { + if _, err := ExternalVolumeClassFromManifest([]byte(tc.raw)); err == nil { + t.Fatalf("ExternalVolumeClassFromManifest(%s) = nil, want error", tc.name) + } + }) + } +} + +func TestExternalVolumeClassesForDriver(t *testing.T) { + root, err := config.RepoRoot() + if err != nil { + t.Fatalf("RepoRoot() = %v", err) + } + cfg := &config.Config{Root: root} + + tests := []struct { + driver string + want []string + }{ + {driver: "none", want: nil}, + {driver: "nfs", want: []string{"csi-nfs"}}, + {driver: "hostpath", want: []string{"csi-hostpath"}}, + {driver: "both", want: []string{"csi-hostpath", "csi-nfs"}}, + } + for _, tc := range tests { + t.Run(tc.driver, func(t *testing.T) { + if err := ValidateCSIDriver(tc.driver); err != nil { + t.Fatalf("ValidateCSIDriver(%q) = %v", tc.driver, err) + } + spec := csiDrivers[tc.driver] + classes, err := externalVolumeClassesForDriver(cfg, spec) + if err != nil { + t.Fatalf("externalVolumeClassesForDriver(%q) = %v", tc.driver, err) + } + if len(classes) != len(tc.want) { + t.Fatalf("len(classes) = %d, want %d", len(classes), len(tc.want)) + } + for i, name := range tc.want { + if classes[i].GetMetadata().GetName() != name { + t.Errorf("classes[%d].name = %q, want %q", i, classes[i].GetMetadata().GetName(), name) + } + } + }) + } + + t.Run("missing manifest returns error", func(t *testing.T) { + if err := ValidateCSIDriver("nfs"); err != nil { + t.Fatalf("ValidateCSIDriver(nfs) = %v", err) + } + if _, err := externalVolumeClassesForDriver(&config.Config{Root: t.TempDir()}, csiDrivers["nfs"]); err == nil { + t.Fatal("externalVolumeClassesForDriver with empty root = nil, want error") + } + }) +} + +func TestRegisterExternalVolumeClassesEarlySkipsAndErrors(t *testing.T) { + root, err := config.RepoRoot() + if err != nil { + t.Fatalf("RepoRoot() = %v", err) + } + + t.Run("unknown driver returns error", func(t *testing.T) { + env := &Env{Cfg: &config.Config{Root: root}} + if err := env.RegisterExternalVolumeClasses(context.Background(), "bogus"); err == nil { + t.Fatal("RegisterExternalVolumeClasses(bogus) = nil, want error") + } + }) + + t.Run("driver none skips with gate enabled", func(t *testing.T) { + env := &Env{Cfg: &config.Config{Root: root, PreviewGates: []string{"ExternalVolumes"}}} + if err := env.RegisterExternalVolumeClasses(context.Background(), "none"); err != nil { + t.Fatalf("RegisterExternalVolumeClasses(none) = %v, want nil", err) + } + }) + + gateOffTests := []struct { + name string + driver string + gates []string + }{ + {name: "nfs empty gates", driver: "nfs", gates: nil}, + {name: "hostpath empty gates", driver: "hostpath", gates: nil}, + {name: "both unrelated gate", driver: "both", gates: []string{"OtherGate"}}, + } + for _, tc := range gateOffTests { + t.Run(tc.name, func(t *testing.T) { + env := &Env{Cfg: &config.Config{Root: root, PreviewGates: tc.gates}} + if err := env.RegisterExternalVolumeClasses(context.Background(), tc.driver); err != nil { + t.Fatalf("RegisterExternalVolumeClasses(%q) with gate off = %v, want nil", tc.driver, err) + } + }) + } + + missingDeploymentTests := []struct { + name string + driver string + gates []string + }{ + {name: "ExternalVolumes gate", driver: "nfs", gates: []string{"ExternalVolumes"}}, + {name: "ALL gate", driver: "both", gates: []string{"ALL"}}, + } + for _, tc := range missingDeploymentTests { + t.Run("skips without ate-api-server "+tc.name, func(t *testing.T) { + env := &Env{ + Cfg: &config.Config{Root: root, PreviewGates: tc.gates}, + Kube: fakeKube(t), + } + if err := env.RegisterExternalVolumeClasses(context.Background(), tc.driver); err != nil { + t.Fatalf("RegisterExternalVolumeClasses(%q) = %v, want nil", tc.driver, err) + } + }) + } +} + +type fakeExternalVolumeClassClient struct { + stored map[string]*ateapi.ExternalVolumeClass + createErr error + getErr error + creates int + gets int +} + +func (f *fakeExternalVolumeClassClient) CreateExternalVolumeClass(_ context.Context, in *ateapi.CreateExternalVolumeClassRequest, _ ...grpc.CallOption) (*ateapi.ExternalVolumeClass, error) { + f.creates++ + if f.createErr != nil { + return nil, f.createErr + } + evc := in.GetExternalVolumeClass() + name := evc.GetMetadata().GetName() + if _, ok := f.stored[name]; ok { + return nil, status.Errorf(codes.AlreadyExists, "external volume class %q already exists", name) + } + f.stored[name] = evc + return evc, nil +} + +func (f *fakeExternalVolumeClassClient) GetExternalVolumeClass(_ context.Context, in *ateapi.GetExternalVolumeClassRequest, _ ...grpc.CallOption) (*ateapi.ExternalVolumeClass, error) { + f.gets++ + if f.getErr != nil { + return nil, f.getErr + } + name := in.GetExternalVolumeClass().GetName() + evc, ok := f.stored[name] + if !ok { + return nil, status.Errorf(codes.NotFound, "external volume class %q not found", name) + } + return evc, nil +} + +func TestRegisterExternalVolumeClassesClient(t *testing.T) { + nfs := &ateapi.ExternalVolumeClass{ + Metadata: &ateapi.ResourceMetadata{Name: "csi-nfs"}, + DriverName: "nfs.csi.k8s.io", + Parameters: map[string]string{"server": "nfs-server.default.svc.cluster.local", "share": "/"}, + MountOptions: []string{"nfsvers=4.1"}, + } + hp := &ateapi.ExternalVolumeClass{ + Metadata: &ateapi.ResourceMetadata{Name: "csi-hostpath"}, + DriverName: "hostpath.csi.k8s.io", + } + + t.Run("creates missing classes", func(t *testing.T) { + client := &fakeExternalVolumeClassClient{stored: map[string]*ateapi.ExternalVolumeClass{}} + if err := registerExternalVolumeClasses(context.Background(), client, []*ateapi.ExternalVolumeClass{nfs, hp}); err != nil { + t.Fatalf("registerExternalVolumeClasses = %v, want nil", err) + } + if client.creates != 2 || client.gets != 0 { + t.Errorf("creates=%d gets=%d, want creates=2 gets=0", client.creates, client.gets) + } + if len(client.stored) != 2 { + t.Errorf("stored %d classes, want 2", len(client.stored)) + } + }) + + t.Run("idempotent on AlreadyExists with matching spec", func(t *testing.T) { + client := &fakeExternalVolumeClassClient{ + stored: map[string]*ateapi.ExternalVolumeClass{ + "csi-nfs": { + Metadata: &ateapi.ResourceMetadata{Name: "csi-nfs", Uid: "uid-1", Version: 3}, + DriverName: "nfs.csi.k8s.io", + Parameters: map[string]string{"server": "nfs-server.default.svc.cluster.local", "share": "/"}, + MountOptions: []string{"nfsvers=4.1"}, + }, + "csi-hostpath": { + Metadata: &ateapi.ResourceMetadata{Name: "csi-hostpath", Uid: "uid-2", Version: 1}, + DriverName: "hostpath.csi.k8s.io", + Parameters: map[string]string{}, + MountOptions: []string{}, + }, + }, + } + if err := registerExternalVolumeClasses(context.Background(), client, []*ateapi.ExternalVolumeClass{nfs, hp}); err != nil { + t.Fatalf("registerExternalVolumeClasses = %v, want nil", err) + } + if client.gets != 2 { + t.Errorf("gets = %d, want 2", client.gets) + } + }) + + mismatchCases := []struct { + name string + existing *ateapi.ExternalVolumeClass + }{ + { + name: "driver mismatch", + existing: &ateapi.ExternalVolumeClass{ + Metadata: &ateapi.ResourceMetadata{Name: "csi-nfs"}, + DriverName: "other.csi.k8s.io", + Parameters: map[string]string{"server": "nfs-server.default.svc.cluster.local", "share": "/"}, + MountOptions: []string{"nfsvers=4.1"}, + }, + }, + { + name: "parameters mismatch", + existing: &ateapi.ExternalVolumeClass{ + Metadata: &ateapi.ResourceMetadata{Name: "csi-nfs"}, + DriverName: "nfs.csi.k8s.io", + Parameters: map[string]string{"server": "other-nfs", "share": "/"}, + MountOptions: []string{"nfsvers=4.1"}, + }, + }, + { + name: "mount options mismatch", + existing: &ateapi.ExternalVolumeClass{ + Metadata: &ateapi.ResourceMetadata{Name: "csi-nfs"}, + DriverName: "nfs.csi.k8s.io", + Parameters: map[string]string{"server": "nfs-server.default.svc.cluster.local", "share": "/"}, + MountOptions: []string{"nfsvers=4.2"}, + }, + }, + } + for _, tc := range mismatchCases { + t.Run("AlreadyExists "+tc.name, func(t *testing.T) { + client := &fakeExternalVolumeClassClient{ + stored: map[string]*ateapi.ExternalVolumeClass{"csi-nfs": tc.existing}, + } + if err := registerExternalVolumeClasses(context.Background(), client, []*ateapi.ExternalVolumeClass{nfs}); err == nil { + t.Fatalf("registerExternalVolumeClasses(%s) = nil, want error", tc.name) + } + }) + } + + t.Run("create error propagated", func(t *testing.T) { + client := &fakeExternalVolumeClassClient{ + stored: map[string]*ateapi.ExternalVolumeClass{}, + createErr: status.Error(codes.Unavailable, "unavailable"), + } + if err := registerExternalVolumeClasses(context.Background(), client, []*ateapi.ExternalVolumeClass{nfs}); err == nil { + t.Fatal("registerExternalVolumeClasses on create error = nil, want error") + } + }) + + t.Run("get error after AlreadyExists propagated", func(t *testing.T) { + client := &fakeExternalVolumeClassClient{ + stored: map[string]*ateapi.ExternalVolumeClass{"csi-nfs": nfs}, + getErr: status.Error(codes.Internal, "internal"), + } + if err := registerExternalVolumeClasses(context.Background(), client, []*ateapi.ExternalVolumeClass{nfs}); err == nil { + t.Fatal("registerExternalVolumeClasses on get error = nil, want error") + } + }) +} diff --git a/hack/csi/external-volume-class-hostpath.yaml b/hack/csi/external-volume-class-hostpath.yaml new file mode 100644 index 0000000000..16f4eab497 --- /dev/null +++ b/hack/csi/external-volume-class-hostpath.yaml @@ -0,0 +1,18 @@ +# Copyright 2026 The Agent Substrate Authors +# +# 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. + +# Canonical ExternalVolumeClass backed by the Kind hostpath CSI driver. +metadata: + name: csi-hostpath +driverName: hostpath.csi.k8s.io diff --git a/hack/csi/external-volume-class-nfs.yaml b/hack/csi/external-volume-class-nfs.yaml new file mode 100644 index 0000000000..07d3e46372 --- /dev/null +++ b/hack/csi/external-volume-class-nfs.yaml @@ -0,0 +1,23 @@ +# Copyright 2026 The Agent Substrate Authors +# +# 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. + +# Canonical ExternalVolumeClass backed by the dev NFS server and csi-driver-nfs. +metadata: + name: csi-nfs +driverName: nfs.csi.k8s.io +parameters: + server: nfs-server.default.svc.cluster.local + share: / +mountOptions: + - nfsvers=4.1 From 895ad0e0edff724319375795fb7fa6375b7c15ac Mon Sep 17 00:00:00 2001 From: Vu Le Date: Wed, 11 Nov 2026 19:24:35 +0000 Subject: [PATCH 19/30] NFS kind script creates the ExternalVolumeClass Signed-off-by: Vu Le --- cmd/ate-setup/internal/steps/csi_test.go | 51 ++++++++++++++++++++++++ hack/setup-csi-nfs-kind.sh | 28 ++++++++++++- 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/cmd/ate-setup/internal/steps/csi_test.go b/cmd/ate-setup/internal/steps/csi_test.go index b8f83ea8b7..a6bd18c6eb 100644 --- a/cmd/ate-setup/internal/steps/csi_test.go +++ b/cmd/ate-setup/internal/steps/csi_test.go @@ -18,6 +18,7 @@ import ( "context" "os" "path/filepath" + "slices" "strconv" "strings" "testing" @@ -168,6 +169,51 @@ func TestTheNFSSetupsApplyTheSharedStorageClass(t *testing.T) { } } +// Both NFS setups register the canonical csi-nfs ExternalVolumeClass from the +// same checked-in manifest so neither carries an inline copy that can drift. +func TestTheNFSSetupsRegisterTheSharedExternalVolumeClass(t *testing.T) { + const manifest = "hack/csi/external-volume-class-nfs.yaml" + root := repoRoot(t) + + raw, err := os.ReadFile(filepath.Join(root, manifest)) + if err != nil { + t.Fatalf("reading %s: %v", manifest, err) + } + class, err := ExternalVolumeClassFromManifest(raw) + if err != nil { + t.Fatalf("parsing %s: %v", manifest, err) + } + if class.GetMetadata().GetName() != "csi-nfs" { + t.Errorf("csi-nfs metadata.name = %q, want csi-nfs", class.GetMetadata().GetName()) + } + if class.GetDriverName() != "nfs.csi.k8s.io" { + t.Errorf("csi-nfs driverName = %q, want nfs.csi.k8s.io", class.GetDriverName()) + } + if !slices.Equal(class.GetMountOptions(), []string{"nfsvers=4.1"}) { + t.Errorf("csi-nfs mountOptions = %v, want [nfsvers=4.1]", class.GetMountOptions()) + } + + goSetup := functionBody(t, "substrate.go", "func externalVolumeClassesForDriver(") + if !strings.Contains(goSetup, `"external-volume-class-nfs.yaml"`) { + t.Errorf("externalVolumeClassesForDriver no longer loads %s", manifest) + } + script, err := os.ReadFile(filepath.Join(root, "hack", "setup-csi-nfs-kind.sh")) + if err != nil { + t.Fatalf("reading the shell setup: %v", err) + } + if !strings.Contains(string(script), manifest) { + t.Errorf("hack/setup-csi-nfs-kind.sh no longer registers %s", manifest) + } + for name, src := range map[string]string{ + "externalVolumeClassesForDriver": goSetup, + "hack/setup-csi-nfs-kind.sh": string(script), + } { + if strings.Contains(src, "\ndriverName:") { + t.Errorf("%s defines an ExternalVolumeClass inline; register %s instead", name, manifest) + } + } +} + // Each --setup-csi value selects the drivers its name says. func TestCSIDriverSpellings(t *testing.T) { for _, tc := range []struct { @@ -247,6 +293,8 @@ func TestTheNFSShellSetupMatchesTheGoSetup(t *testing.T) { "serverName: csi-nfs-controller.kube-system.svc\n", "usePodIdentity: true", "/sa/ate-api-server", + "ExternalVolumes", + "--preview create external-volume-class -f", } { if !strings.Contains(src, required) { t.Errorf("hack/setup-csi-nfs-kind.sh no longer contains %q", required) @@ -255,6 +303,9 @@ func TestTheNFSShellSetupMatchesTheGoSetup(t *testing.T) { if service, driver := strings.Index(src, "name: csi-nfs-controller\n namespace: kube-system"), strings.Index(src, "csi-nfs-controller.yaml"); service < 0 || driver < 0 || service > driver { t.Error("hack/setup-csi-nfs-kind.sh deploys the NFS driver before creating the csi-nfs-controller Service") } + if cdc, evc := strings.Index(src, "kind: CSIDriverConfig"), strings.Index(src, "external-volume-class-nfs.yaml"); cdc < 0 || evc < 0 || cdc > evc { + t.Error("hack/setup-csi-nfs-kind.sh registers the csi-nfs ExternalVolumeClass before creating the CSIDriverConfig") + } } // The hostpath proxy needs no more than root to reach the driver's socket. diff --git a/hack/setup-csi-nfs-kind.sh b/hack/setup-csi-nfs-kind.sh index f6091d8656..1b4c307bf0 100755 --- a/hack/setup-csi-nfs-kind.sh +++ b/hack/setup-csi-nfs-kind.sh @@ -254,7 +254,33 @@ spec: serverName: csi-nfs-controller.kube-system.svc EOF -# 9. Restart atelet to ensure it reconnects to the new CSI socket. +# 9. Register the canonical ExternalVolumeClass when ExternalVolumes preview is enabled. +preview_gates="${ATE_PREVIEW:-}" +case ",${preview_gates//[[:space:]]/}," in + *,ALL,*|*,ExternalVolumes,*) + if kubectl get deployment/ate-api-server -n "${ATE_NAMESPACE}" >/dev/null 2>&1; then + kubectl rollout status deployment/ate-api-server -n "${ATE_NAMESPACE}" --timeout=120s + echo "Registering csi-nfs ExternalVolumeClass..." + if create_out="$(go -C "${ROOT}" run ./cmd/kubectl-ate --preview create external-volume-class -f "${ROOT}/hack/csi/external-volume-class-nfs.yaml" 2>&1)"; then + printf '%s\n' "${create_out}" + elif [[ "${create_out}" == *"AlreadyExists"* ]]; then + # Keep an existing csi-nfs for idempotence without duplicating manifest fields here; + # ate-setup setup csi compares specs via proto unmarshaling. + echo "ExternalVolumeClass csi-nfs already exists; keeping it." + else + printf '%s\n' "${create_out}" >&2 + exit 1 + fi + else + echo "ate-api-server not found; skipping csi-nfs ExternalVolumeClass registration." + fi + ;; + *) + echo "Skipping csi-nfs ExternalVolumeClass registration: ExternalVolumes preview gate is disabled (set ATE_PREVIEW=ExternalVolumes)." + ;; +esac + +# 10. Restart atelet to ensure it reconnects to the new CSI socket. echo "Restarting atelet DaemonSet (if present)..." kubectl rollout restart daemonset/atelet -n "${ATE_NAMESPACE}" >/dev/null 2>&1 || true From 845eb41cb64c82ca816126930caa24142d606b48 Mon Sep 17 00:00:00 2001 From: Vu Le Date: Wed, 11 Nov 2026 22:04:54 +0000 Subject: [PATCH 20/30] counter demo and manual demo templates Signed-off-by: Vu Le --- cmd/ate-setup/commands.md | 2 +- .../internal/demos/counter/counter.go | 13 ++++--- .../internal/demos/counter/counter_test.go | 37 ++++++++++--------- demos/counter/README.md | 20 +++++----- .../counter-microvm-csi-test-template.yaml | 3 +- demos/sandbox/manual-test-multi-template.yaml | 6 ++- 6 files changed, 43 insertions(+), 38 deletions(-) diff --git a/cmd/ate-setup/commands.md b/cmd/ate-setup/commands.md index d019f09119..f1378ab8b1 100644 --- a/cmd/ate-setup/commands.md +++ b/cmd/ate-setup/commands.md @@ -200,7 +200,7 @@ is absent); the other two are flags of the benchmark commands. See | Command | Description | |---|---| | `deploy demo counter` | A counter actor exercising snapshot, resume, and atenet ingress | -| `deploy demo counter --with-external-volume [--storage-class NAME]` | The same, plus an external volume and a pre-seeded file to validate (requires `--preview=ExternalVolumes`). Run `setup csi` first and name the class it created, e.g. `csi-nfs-sc`; defaults to `standard` | +| `deploy demo counter --with-external-volume [--external-volume-class NAME]` | The same, plus an external volume and a pre-seeded file to validate (requires `--preview=ExternalVolumes`). Run `setup csi --preview=ExternalVolumes` first and name the class it registered, e.g. `csi-nfs`; defaults to `csi-nfs` | | `deploy demo counter-microvm` | The counter demo on microVM workers | | `deploy demo egress` | Egress policy enforcement through atenet; the actors trust the egress gateway's CA | | `deploy demo egress-microvm` | The same on microVM workers | diff --git a/cmd/ate-setup/internal/demos/counter/counter.go b/cmd/ate-setup/internal/demos/counter/counter.go index 9f95fa9998..321049013a 100644 --- a/cmd/ate-setup/internal/demos/counter/counter.go +++ b/cmd/ate-setup/internal/demos/counter/counter.go @@ -30,11 +30,11 @@ const ( namespace = "ate-demo-counter" template = "demos/counter/counter-template.yaml.tmpl" - defaultStorageClass = "standard" + defaultExternalVolumeClass = "csi-nfs" ) func (d *demo) externalVolumeValues(e *steps.Env) map[string]string { - sc := e.Cfg.Resolved().String("demo.counter.storageClass") + evc := e.Cfg.Resolved().String("demo.counter.externalVolumeClass") return map[string]string{ "VALIDATE_EXISTING_FILE_PATH_ARG": " - --validate-existing-file-path=/external-data/test.txt", "EXTERNAL_VOLUME_MOUNTS": " - name: external-data\n" + @@ -43,7 +43,8 @@ func (d *demo) externalVolumeValues(e *steps.Env) map[string]string { " external:\n" + " template:\n" + " capacityBytes: 1073741824 # 1Gi\n" + - " storageClassName: " + sc, + " externalVolumeClass:\n" + + " name: " + evc, } } @@ -79,9 +80,9 @@ func (d *demo) Settings() []config.Setting { Usage: "Attach an external volume and validate a pre-seeded file on it (run \"setup csi\" first)", }, { - Key: "demo.counter.storageClass", Env: "STORAGE_CLASS", - Flag: "storage-class", Kind: config.KindString, Default: defaultStorageClass, - Usage: "StorageClass backing the external volume, e.g. csi-nfs-sc or csi-hostpath-sc. Must be used --with-external-volume=true.", + Key: "demo.counter.externalVolumeClass", Env: "EXTERNAL_VOLUME_CLASS", + Flag: "external-volume-class", Kind: config.KindString, Default: defaultExternalVolumeClass, + Usage: "ExternalVolumeClass backing the external volume, e.g. csi-nfs or csi-hostpath. Must be used --with-external-volume=true.", }, } } diff --git a/cmd/ate-setup/internal/demos/counter/counter_test.go b/cmd/ate-setup/internal/demos/counter/counter_test.go index beda14bc8e..7a69a02791 100644 --- a/cmd/ate-setup/internal/demos/counter/counter_test.go +++ b/cmd/ate-setup/internal/demos/counter/counter_test.go @@ -31,31 +31,31 @@ import ( // sweep test in the demos package. func TestExternalVolumeRenders(t *testing.T) { for _, tc := range []struct { - name string - storageClass string - wantSC string + name string + externalVolumeClass string + wantEVC string }{ { - name: "unset", - storageClass: "", - wantSC: "storageClassName: standard", + name: "unset", + externalVolumeClass: "", + wantEVC: "name: csi-nfs", }, { - name: "explicit", - storageClass: "csi-nfs-sc", - wantSC: "storageClassName: csi-nfs-sc", + name: "explicit", + externalVolumeClass: "csi-hostpath", + wantEVC: "name: csi-hostpath", }, } { t.Run(tc.name, func(t *testing.T) { - // The storage class is a setting now, so steer it the way an - // operator would rather than by reaching into the demo. Unset, - // not blanked, for the case that wants the default: an exported - // empty value is a storage class the operator asked for. - if tc.storageClass == "" { - t.Setenv("STORAGE_CLASS", "x") - _ = os.Unsetenv("STORAGE_CLASS") + // The external volume class is a setting, so steer it the way an + // operator would rather than by reaching into the demo. Unset, not + // blanked, for the case that wants the default: an exported empty + // value is a class name the operator asked for. + if tc.externalVolumeClass == "" { + t.Setenv("EXTERNAL_VOLUME_CLASS", "x") + _ = os.Unsetenv("EXTERNAL_VOLUME_CLASS") } else { - t.Setenv("STORAGE_CLASS", tc.storageClass) + t.Setenv("EXTERNAL_VOLUME_CLASS", tc.externalVolumeClass) } e := demotest.Env(t) d := &demo{} @@ -71,7 +71,8 @@ func TestExternalVolumeRenders(t *testing.T) { "mountPath: /external-data", "external:", "template:", - tc.wantSC, + "externalVolumeClass:", + tc.wantEVC, } { if !strings.Contains(string(manifest), want) { t.Errorf("rendered manifest is missing %q", want) diff --git a/demos/counter/README.md b/demos/counter/README.md index 0aa17b89ea..3c3a5af51e 100644 --- a/demos/counter/README.md +++ b/demos/counter/README.md @@ -201,18 +201,18 @@ go run ./cmd/ate-setup deploy ate-system \ --credential-provider='{"name":"k8s.io"}' \ --ingress-allowed-spiffe-ids=spiffe://cluster.local/ns/ate-system/sa/atenet-client -# 2. Install a bundled CSI driver and its CSIDriverConfig: -# - NFS (creates StorageClass csi-nfs-sc, requires the nfsd kernel module on nodes): -go run ./cmd/ate-setup setup csi nfs -# - Or hostpath on kind clusters (creates StorageClass csi-hostpath-sc): -# go run ./cmd/ate-setup setup csi hostpath +# 2. Install a bundled CSI driver, its CSIDriverConfig, and its ExternalVolumeClass: +# - NFS (registers ExternalVolumeClass csi-nfs, requires the nfsd kernel module on nodes): +go run ./cmd/ate-setup setup csi nfs --preview=ExternalVolumes +# - Or hostpath on kind clusters (registers ExternalVolumeClass csi-hostpath): +# go run ./cmd/ate-setup setup csi hostpath --preview=ExternalVolumes # 3. Delete any existing counter demo (templates are immutable), then deploy with the external volume go run ./cmd/ate-setup delete demo counter kubectl wait --for=delete namespace/ate-demo-counter --timeout=60s go run ./cmd/ate-setup deploy demo counter \ --with-external-volume \ - --storage-class=csi-nfs-sc \ + --external-volume-class=csi-nfs \ --preview=ExternalVolumes # 4. Create the actor with --preview enabled on kubectl ate @@ -223,10 +223,10 @@ kubectl ate --preview create actor my-counter-1 -a ate-demo-counter --template c The installer reads these settings in addition to those in [docs/guides/operator-install.md](../../docs/guides/operator-install.md#settings), through the same flag, environment variable, and configuration document channels. -| Key | Environment variable | Flag | Default | Applies to | -|-----------------------------------|-----------------------------------------|--------------------------|------------|-----------------------| -| `demo.counter.storageClass` | `STORAGE_CLASS` | `--storage-class` | `standard` | `deploy demo counter` | -| `demo.counter.withExternalVolume` | `ATE_DEMO_COUNTER_WITH_EXTERNAL_VOLUME` | `--with-external-volume` | `false` | `deploy demo counter` | +| Key | Environment variable | Flag | Default | Applies to | +|------------------------------------|-----------------------------------------|---------------------------|-----------|-----------------------| +| `demo.counter.externalVolumeClass` | `EXTERNAL_VOLUME_CLASS` | `--external-volume-class` | `csi-nfs` | `deploy demo counter` | +| `demo.counter.withExternalVolume` | `ATE_DEMO_COUNTER_WITH_EXTERNAL_VOLUME` | `--with-external-volume` | `false` | `deploy demo counter` | ## How to Uninstall diff --git a/demos/counter/counter-microvm-csi-test-template.yaml b/demos/counter/counter-microvm-csi-test-template.yaml index f62f43addc..9683f728e0 100644 --- a/demos/counter/counter-microvm-csi-test-template.yaml +++ b/demos/counter/counter-microvm-csi-test-template.yaml @@ -45,4 +45,5 @@ volumes: external: template: capacityBytes: 1073741824 # 1Gi - storageClassName: csi-hostpath-sc + externalVolumeClass: + name: csi-hostpath diff --git a/demos/sandbox/manual-test-multi-template.yaml b/demos/sandbox/manual-test-multi-template.yaml index b40b8ffb90..f973881539 100644 --- a/demos/sandbox/manual-test-multi-template.yaml +++ b/demos/sandbox/manual-test-multi-template.yaml @@ -47,9 +47,11 @@ volumes: external: template: capacityBytes: 1073741824 # 1Gi - storageClassName: csi-hostpath-sc + externalVolumeClass: + name: csi-hostpath - name: vol-nfs external: template: capacityBytes: 1073741824 # 1Gi - storageClassName: csi-nfs-sc + externalVolumeClass: + name: csi-nfs From e01dcb09aecf13c98ea9c1da184c5fd5aaa846fe Mon Sep 17 00:00:00 2001 From: Vu Le Date: Wed, 11 Nov 2026 22:05:08 +0000 Subject: [PATCH 21/30] e2e suites and benchmarking workloads Signed-off-by: Vu Le --- benchmarking/deploy_locust.sh | 15 +++--- benchmarking/workloads/deploy.sh | 46 ++++++++++-------- .../glutton-storage-template.yaml.tmpl | 7 +-- .../internal/steps/substrate_test.go | 16 +++++-- hack/run-e2e.sh | 2 +- .../combinedvolumes/combinedvolumes_test.go | 48 +++++++++++-------- internal/e2e/suites/demo/demo_test.go | 20 ++++---- internal/e2e/testmain.go | 10 ++-- 8 files changed, 92 insertions(+), 72 deletions(-) diff --git a/benchmarking/deploy_locust.sh b/benchmarking/deploy_locust.sh index bf207fa68c..9b9b60cbc5 100755 --- a/benchmarking/deploy_locust.sh +++ b/benchmarking/deploy_locust.sh @@ -35,7 +35,7 @@ ACTOR_MEMORY="" ACTOR_CPU="" # Empty leaves the WorkerPool pods unsized. WORKER_MEMORY="" -STORAGE_CLASS_NAME="" +EXTERNAL_VOLUME_CLASS="${EXTERNAL_VOLUME_CLASS:-}" WAIT_TIMEOUT_SECS="" usage() { @@ -54,8 +54,9 @@ usage() { echo " ActorTemplates (default: 1)." echo " --worker-memory SIZE Forwarded to workloads/deploy.sh. Memory request and limit" echo " for each WorkerPool pod (default: unset, the pod is unsized)." - echo " --storage-class-name S Forwarded to workloads/deploy.sh. StorageClass for the glutton-storage" - echo " external volume; setting it deploys glutton-storage." + echo " --external-volume-class S" + echo " Forwarded to workloads/deploy.sh. ExternalVolumeClass for the" + echo " glutton-storage external volume; setting it deploys glutton-storage." echo " --wait-timeout SECONDS Forwarded to workloads/deploy.sh. The timeout in seconds for" echo " waiting for the workers to be ready (default: 300)" echo " --skip-build Skip locust image build/push (use the existing :latest image)" @@ -88,8 +89,8 @@ while [[ "$#" -gt 0 ]]; do --actor-cpu=*) ACTOR_CPU="${1#*=}" ;; --worker-memory) shift; WORKER_MEMORY="$1" ;; --worker-memory=*) WORKER_MEMORY="${1#*=}" ;; - --storage-class-name) shift; STORAGE_CLASS_NAME="$1" ;; - --storage-class-name=*) STORAGE_CLASS_NAME="${1#*=}" ;; + --external-volume-class) shift; EXTERNAL_VOLUME_CLASS="$1" ;; + --external-volume-class=*) EXTERNAL_VOLUME_CLASS="${1#*=}" ;; --wait-timeout) shift; WAIT_TIMEOUT_SECS="$1" ;; --wait-timeout=*) WAIT_TIMEOUT_SECS="${1#*=}" ;; --skip-build) SKIP_BUILD=1 ;; @@ -134,8 +135,8 @@ if [[ "${action}" == "deploy" ]]; then if [[ -n "${WORKER_MEMORY}" ]]; then workload_args+=(--worker-memory "${WORKER_MEMORY}") fi - if [[ -n "${STORAGE_CLASS_NAME}" ]]; then - workload_args+=(--storage-class-name "${STORAGE_CLASS_NAME}") + if [[ -n "${EXTERNAL_VOLUME_CLASS}" ]]; then + workload_args+=(--external-volume-class "${EXTERNAL_VOLUME_CLASS}") fi if [[ -n "${WAIT_TIMEOUT_SECS}" ]]; then workload_args+=(--wait-timeout "${WAIT_TIMEOUT_SECS}") diff --git a/benchmarking/workloads/deploy.sh b/benchmarking/workloads/deploy.sh index 74b41ed589..101811b6c2 100755 --- a/benchmarking/workloads/deploy.sh +++ b/benchmarking/workloads/deploy.sh @@ -32,8 +32,8 @@ SWEPERF_TEMPLATE_DIR="${MANIFEST_DIR}/sweperf/generated" # read from SWEPERF_TEMPLATE_DIR, the rest from MANIFEST_DIR. WORKLOAD_TEMPLATES # overrides the default set — the usermem and kernelmem templates (for the # matching locust tests) are not deployed by default. The glutton-storage -# template is added when a StorageClass is set, because it needs a CSI driver -# that not every cluster has; ate-env is added when ATE_ENV_IMAGE is set. +# template is added when an ExternalVolumeClass is set, because it needs a CSI +# driver that not every cluster has; ate-env is added when ATE_ENV_IMAGE is set. read -r -a TEMPLATES <<<"${WORKLOAD_TEMPLATES:-sleep glutton glutton-durdir-data glutton-durdir-full}" # template_manifest prints the manifest path for ActorTemplate NAME. @@ -63,9 +63,9 @@ ACTOR_CPU="1" # and limit. Empty leaves the pod unsized. The limit, less what the worker # keeps for itself, is the memory it reports as its actor capacity. WORKER_MEMORY="" -# The StorageClass for the glutton-storage external volume. Empty means the -# template is not deployed. -STORAGE_CLASS_NAME="${STORAGE_CLASS_NAME:-}" +# The ExternalVolumeClass for the glutton-storage external volume. Empty means +# the template is not deployed. +EXTERNAL_VOLUME_CLASS="${EXTERNAL_VOLUME_CLASS:-}" # The image for the ate-env benchmark ActorTemplate. Empty means the # template is not deployed. ATE_ENV_IMAGE="${ATE_ENV_IMAGE:-}" @@ -92,8 +92,10 @@ usage() { echo " --actor-cpu CPU CPU limit for the benchmark ActorTemplates (default: 1)" echo " --worker-memory SIZE Memory request and limit for each WorkerPool pod" echo " (default: unset, the pod is unsized)" - echo " --storage-class-name NAME StorageClass for the glutton-storage external volume. Setting it" - echo " deploys glutton-storage (default: not deployed). Env: STORAGE_CLASS_NAME." + echo " --external-volume-class NAME" + echo " ExternalVolumeClass for the glutton-storage external volume. Setting" + echo " it deploys glutton-storage (default: not deployed)." + echo " Env: EXTERNAL_VOLUME_CLASS." echo " --otlp-endpoint URL The address to which an instrumented actor container" echo " sends telemetry (default: the endpoint in the" echo " ate-otel-config ConfigMap)" @@ -193,7 +195,7 @@ substitute() { -e "s|\${ACTOR_CPU_MILLICORES}|${ACTOR_CPU_MILLICORES}|g" \ -e "s|\${WORKER_RESOURCES}|${worker_resources}|g" \ -e "s|\${ATE_ENV_IMAGE}|${ATE_ENV_IMAGE:-}|g" \ - -e "s|\${STORAGE_CLASS_NAME}|${STORAGE_CLASS_NAME}|g" \ + -e "s|\${EXTERNAL_VOLUME_CLASS}|${EXTERNAL_VOLUME_CLASS}|g" \ "${manifest}" } @@ -302,7 +304,7 @@ deploy() { fi ACTOR_CPU_MILLICORES="$(cpu_millicores "${ACTOR_CPU}")" ACTOR_MEMORY_BYTES="$(memory_bytes "${ACTOR_MEMORY}")" - echo "Deploying workloads (worker_count=${WORKER_COUNT}, actor_memory=${ACTOR_MEMORY}, actor_cpu=${ACTOR_CPU}, worker_memory=${WORKER_MEMORY:-unset}, storage_class=${STORAGE_CLASS_NAME:-none}, otlp_endpoint=${OTLP_ENDPOINT})..." + echo "Deploying workloads (worker_count=${WORKER_COUNT}, actor_memory=${ACTOR_MEMORY}, actor_cpu=${ACTOR_CPU}, worker_memory=${WORKER_MEMORY:-unset}, external_volume_class=${EXTERNAL_VOLUME_CLASS:-none}, otlp_endpoint=${OTLP_ENDPOINT})..." substitute "${POOL_MANIFEST}" | hack/run-tool.sh ko apply -f - echo "Waiting for worker pool to be ready (timeout: ${WAIT_TIMEOUT_SECS}s)..." if fake_data_plane; then @@ -332,11 +334,15 @@ deploy() { for template in "${TEMPLATES[@]}"; do run_kubectl_ate delete actor-template "${template}" -a benchmark-workloads \ >/dev/null 2>&1 || true + local create_args=(create actor-template -f -) + if [[ "${template}" == "glutton-storage" ]]; then + create_args=(--preview "${create_args[@]}") + fi # ko resolve builds the ko:// image references and replaces them with # pushed digests before the manifest reaches kubectl-ate. substitute "$(template_manifest "${template}")" \ | hack/run-tool.sh ko resolve -f - \ - | run_kubectl_ate create actor-template -f - + | run_kubectl_ate "${create_args[@]}" done wait_templates_ready @@ -412,12 +418,12 @@ while [[ "$#" -gt 0 ]]; do --worker-memory=*) WORKER_MEMORY="${1#*=}" ;; - --storage-class-name) + --external-volume-class) shift - STORAGE_CLASS_NAME="$1" + EXTERNAL_VOLUME_CLASS="$1" ;; - --storage-class-name=*) - STORAGE_CLASS_NAME="${1#*=}" + --external-volume-class=*) + EXTERNAL_VOLUME_CLASS="${1#*=}" ;; --wait-timeout) shift @@ -459,11 +465,11 @@ if ! [[ "${WAIT_TIMEOUT_SECS}" =~ ^[0-9]+$ ]]; then exit 1 fi -# glutton-storage joins the default set only when it has a StorageClass. Delete -# always includes it, because deleting a template that does not exist is a -# no-op. +# glutton-storage joins the default set only when it has an ExternalVolumeClass. +# Delete always includes it, because deleting a template that does not exist is +# a no-op. if [[ -z "${WORKLOAD_TEMPLATES:-}" ]] \ - && { [[ -n "${STORAGE_CLASS_NAME}" ]] || [[ "${action}" == "delete" ]]; }; then + && { [[ -n "${EXTERNAL_VOLUME_CLASS}" ]] || [[ "${action}" == "delete" ]]; }; then TEMPLATES+=(glutton-storage) fi @@ -474,8 +480,8 @@ if [[ -z "${WORKLOAD_TEMPLATES:-}" ]] \ TEMPLATES+=(ate-env) fi -if [[ "${action}" == "deploy" && -z "${STORAGE_CLASS_NAME}" && " ${TEMPLATES[*]} " == *" glutton-storage "* ]]; then - echo "Error: the glutton-storage template needs --storage-class-name" >&2 +if [[ "${action}" == "deploy" && -z "${EXTERNAL_VOLUME_CLASS}" && " ${TEMPLATES[*]} " == *" glutton-storage "* ]]; then + echo "Error: the glutton-storage template needs --external-volume-class" >&2 exit 1 fi diff --git a/benchmarking/workloads/manifests/glutton-storage-template.yaml.tmpl b/benchmarking/workloads/manifests/glutton-storage-template.yaml.tmpl index 21a67243c2..eebbb8edc5 100644 --- a/benchmarking/workloads/manifests/glutton-storage-template.yaml.tmpl +++ b/benchmarking/workloads/manifests/glutton-storage-template.yaml.tmpl @@ -14,7 +14,7 @@ # ActorTemplate (protojson-shaped ateapi.ActorTemplate) for the glutton-storage # benchmark workload, created through the ate API by workloads/deploy.sh. -# Attaches an external volume backed by ${STORAGE_CLASS_NAME}. The DurDir load +# Attaches an external volume backed by ${EXTERNAL_VOLUME_CLASS}. The DurDir load # runs it with --durdir-template glutton-storage. metadata: atespace: benchmark-workloads @@ -27,7 +27,8 @@ volumes: external: template: capacityBytes: 1073741824 # 1Gi - storageClassName: ${STORAGE_CLASS_NAME} + externalVolumeClass: + name: ${EXTERNAL_VOLUME_CLASS} containers: - name: glutton-storage image: ko://go.ate.dev/substrate/cmd/benchmarking/glutton @@ -56,4 +57,4 @@ resources: cpuMillicores: "${ACTOR_CPU_MILLICORES}" memoryBytes: "${ACTOR_MEMORY_BYTES}" snapshotConfig: - onCommit: SNAPSHOT_CONTENT_SCOPE_FULL + preferredFidelity: SNAPSHOT_FIDELITY_MEMORY diff --git a/cmd/ate-setup/internal/steps/substrate_test.go b/cmd/ate-setup/internal/steps/substrate_test.go index 503e584a6f..f6f4a94781 100644 --- a/cmd/ate-setup/internal/steps/substrate_test.go +++ b/cmd/ate-setup/internal/steps/substrate_test.go @@ -44,11 +44,12 @@ func TestActorTemplateFromManifestDemos(t *testing.T) { // The values benchmarking/workloads/deploy.sh substitutes. benchmarkValues := map[string]string{ - "${ACTOR_CPU_MILLICORES}": "1000", - "${ACTOR_MEMORY_BYTES}": "268435456", - "${ACTOR_MEMORY}": "256Mi", - "${ATE_ENV_IMAGE}": "gcr.io/example/ate-env-guest@sha256:1d38934ef1dac71fcb1f1286de734e06ab2e19747279bccbd37bfe69e0d5bc72", - "${OTLP_ENDPOINT}": "http://otel-collector.otel-system:4317", + "${ACTOR_CPU_MILLICORES}": "1000", + "${ACTOR_MEMORY_BYTES}": "268435456", + "${ACTOR_MEMORY}": "256Mi", + "${ATE_ENV_IMAGE}": "gcr.io/example/ate-env-guest@sha256:1d38934ef1dac71fcb1f1286de734e06ab2e19747279bccbd37bfe69e0d5bc72", + "${EXTERNAL_VOLUME_CLASS}": "csi-nfs", + "${OTLP_ENDPOINT}": "http://otel-collector.otel-system:4317", } tests := []struct { @@ -93,6 +94,11 @@ func TestActorTemplateFromManifestDemos(t *testing.T) { values: benchmarkValues, want: resources.ActorTemplateRef{Atespace: "benchmark-workloads", Name: "glutton-durdir-full"}, }, + { + relPath: "benchmarking/workloads/manifests/glutton-storage-template.yaml.tmpl", + values: benchmarkValues, + want: resources.ActorTemplateRef{Atespace: "benchmark-workloads", Name: "glutton-storage"}, + }, { relPath: "benchmarking/workloads/manifests/usermem-template.yaml.tmpl", values: benchmarkValues, diff --git a/hack/run-e2e.sh b/hack/run-e2e.sh index 4167ccb4fa..b3809ad888 100755 --- a/hack/run-e2e.sh +++ b/hack/run-e2e.sh @@ -49,7 +49,7 @@ Common E2E Flags (passed after -args): --no-color Disable colored output --kube-config Path to kubeconfig file --kube-context Kubernetes context to use - --storage-class StorageClass to use for external volume tests (default: csi-nfs-sc) + --external-volume-class ExternalVolumeClass to use for external volume tests (default: csi-nfs) --preview Preview gates the cluster was installed with ("ALL" for all) Common Go Test Flags (passed before -args): diff --git a/internal/e2e/suites/combinedvolumes/combinedvolumes_test.go b/internal/e2e/suites/combinedvolumes/combinedvolumes_test.go index cf16d686bc..12aaf82301 100644 --- a/internal/e2e/suites/combinedvolumes/combinedvolumes_test.go +++ b/internal/e2e/suites/combinedvolumes/combinedvolumes_test.go @@ -41,7 +41,8 @@ import ( "go.ate.dev/substrate/internal/e2e" "go.ate.dev/substrate/internal/preview" "go.ate.dev/substrate/internal/resources" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) const ( @@ -155,31 +156,36 @@ func buildFixtureImage(t *testing.T, repo string) string { return fmt.Sprintf("%s@%s", tag.Context().Name(), digest) } -// storageClassOrEmpty returns the configured StorageClass if external volumes -// are enabled and the cluster has the class, and "" if not. External volumes -// are a preview feature and the CSI driver is optional, so either missing -// drops the external volume from the template instead of failing every test -// in the suite. -func storageClassOrEmpty(ctx context.Context, t *testing.T, clients *e2e.Clients) string { +// externalVolumeClassOrEmpty returns the configured ExternalVolumeClass if +// external volumes are enabled and the class is registered, and "" if not. +// External volumes are a preview feature and the CSI driver is optional, so +// either missing drops the external volume from the template instead of +// failing every test in the suite. +func externalVolumeClassOrEmpty(ctx context.Context, t *testing.T, clients *e2e.Clients) string { t.Helper() if !preview.IsEnabled(preview.GateExternalVolumes) { t.Logf("preview gate %q is not enabled; the external-volume cases will be skipped", preview.GateExternalVolumes) return "" } - if _, err := clients.K8s.StorageV1().StorageClasses().Get(ctx, e2e.StorageClass, metav1.GetOptions{}); err != nil { - t.Logf("StorageClass %q not found (%v); the external-volume case will be skipped", e2e.StorageClass, err) - return "" + if _, err := clients.SubstrateAPI.GetExternalVolumeClass(ctx, &ateapi.GetExternalVolumeClassRequest{ + ExternalVolumeClass: &ateapi.ObjectRef{Name: e2e.ExternalVolumeClass}, + }); err != nil { + if status.Code(err) == codes.NotFound { + t.Logf("ExternalVolumeClass %q not found; the external-volume case will be skipped", e2e.ExternalVolumeClass) + return "" + } + t.Fatalf("GetExternalVolumeClass(%q): %v", e2e.ExternalVolumeClass, err) } - return e2e.StorageClass + return e2e.ExternalVolumeClass } // createTemplate builds a probe ActorTemplate with the fixture attached as an // image volume, copying the resolved runtime from the shared probe template. // The template's name is suffixed per test run: it lives in the suite's // shared atespace, which outlives the per-test k8s namespace. A non-empty -// storageClass adds the external volume. -func createTemplate(ctx context.Context, t *testing.T, clients *e2e.Clients, ns *e2e.Namespace, fixtureImage, storageClass string) *ateapi.ActorTemplate { +// externalVolumeClass adds the external volume. +func createTemplate(ctx context.Context, t *testing.T, clients *e2e.Clients, ns *e2e.Namespace, fixtureImage, externalVolumeClass string) *ateapi.ActorTemplate { t.Helper() // The probe supplies this suite's container image and resolved runtime. @@ -221,7 +227,7 @@ func createTemplate(ctx context.Context, t *testing.T, clients *e2e.Clients, ns Name: "scratch", DurableDir: &ateapi.DurableDirVolumeSource{}, }) - if storageClass == "" { + if externalVolumeClass == "" { return } tmpl.Containers[0].VolumeMounts = append(tmpl.Containers[0].VolumeMounts, @@ -230,8 +236,8 @@ func createTemplate(ctx context.Context, t *testing.T, clients *e2e.Clients, ns tmpl.Volumes = append(tmpl.Volumes, &ateapi.Volume{ Name: extVolume, External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - CapacityBytes: extCapacity, - StorageClassName: storageClass, + CapacityBytes: extCapacity, + ExternalVolumeClass: &ateapi.ObjectRef{Name: externalVolumeClass}, }}, }) }, @@ -358,8 +364,8 @@ func TestCombinedVolumes(t *testing.T) { fixtureImage := buildFixtureImage(t, repo) t.Logf("fixture image: %s", fixtureImage) - storageClass := storageClassOrEmpty(ctx, t, clients) - tmpl := createTemplate(ctx, t, clients, ns, fixtureImage, storageClass) + externalVolumeClass := externalVolumeClassOrEmpty(ctx, t, clients) + tmpl := createTemplate(ctx, t, clients, ns, fixtureImage, externalVolumeClass) actorRef := resources.ActorRef{Atespace: atespace, Name: "cv-" + ns.Name} if _, err := clients.SubstrateAPI.CreateActor(ctx, &ateapi.CreateActorRequest{ @@ -392,8 +398,8 @@ func TestCombinedVolumes(t *testing.T) { requireExternalVolume := func(t *testing.T) { t.Helper() e2e.RequirePreview(t, preview.GateExternalVolumes) - if storageClass == "" { - t.Skipf("StorageClass %q is not installed", e2e.StorageClass) + if externalVolumeClass == "" { + t.Skipf("ExternalVolumeClass %q is not registered", e2e.ExternalVolumeClass) } } @@ -461,7 +467,7 @@ func TestCombinedVolumes(t *testing.T) { // Written after the suspend above, so it is in no snapshot the revert // can return the actor to. requireWrite(ctx, t, router, actorRef, scratchPathA+"/"+postSnapshotName) - if storageClass != "" { + if externalVolumeClass != "" { requireWrite(ctx, t, router, actorRef, extPathA+"/"+postSnapshotName) } diff --git a/internal/e2e/suites/demo/demo_test.go b/internal/e2e/suites/demo/demo_test.go index ea9016483c..f0a55ad8b9 100644 --- a/internal/e2e/suites/demo/demo_test.go +++ b/internal/e2e/suites/demo/demo_test.go @@ -1664,9 +1664,14 @@ func createActorTemplate(ctx context.Context, t *testing.T, clients *e2e.Clients } func createActorTemplateWithExternalVolume(ctx context.Context, t *testing.T, clients *e2e.Clients, nsObj *e2e.Namespace, fidelity ateapi.SnapshotFidelity) (*ateapi.ActorTemplate, error) { - scName := e2e.StorageClass - if !hasStorageClass(ctx, clients, scName) { - t.Fatalf("StorageClass %q not found in cluster; provide a valid --storage-class or install the CSI driver via --setup-csi", scName) + className := e2e.ExternalVolumeClass + if _, err := clients.SubstrateAPI.GetExternalVolumeClass(ctx, &ateapi.GetExternalVolumeClassRequest{ + ExternalVolumeClass: &ateapi.ObjectRef{Name: className}, + }); err != nil { + if status.Code(err) == codes.NotFound { + t.Fatalf("ExternalVolumeClass %q not found; provide a valid --external-volume-class or install the CSI driver via --setup-csi", className) + } + t.Fatalf("GetExternalVolumeClass(%q): %v", className, err) } modify := func(at *ateapi.ActorTemplate) { @@ -1702,8 +1707,8 @@ func createActorTemplateWithExternalVolume(ctx context.Context, t *testing.T, cl at.Volumes = append(at.Volumes, &ateapi.Volume{ Name: "external-data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - CapacityBytes: 1 << 30, - StorageClassName: scName, + CapacityBytes: 1 << 30, + ExternalVolumeClass: &ateapi.ObjectRef{Name: className}, }}, }) } @@ -1742,11 +1747,6 @@ func createActorTemplateWithTwoDurableDirs(ctx context.Context, t *testing.T, cl return createActorTemplateInternal(ctx, t, clients, nsObj, "counter-two-durabledirs", fidelity, modify) } -func hasStorageClass(ctx context.Context, clients *e2e.Clients, name string) bool { - _, err := clients.K8s.StorageV1().StorageClasses().Get(ctx, name, metav1.GetOptions{}) - return err == nil -} - func waitForActorState(ctx context.Context, t *testing.T, clients *e2e.Clients, actorName string, expectedState ateapi.ActorState) { waitForActorStateWithTimeout(ctx, t, clients, actorName, expectedState, 60*time.Second) } diff --git a/internal/e2e/testmain.go b/internal/e2e/testmain.go index 4d3bb355ec..30b04ebd7b 100644 --- a/internal/e2e/testmain.go +++ b/internal/e2e/testmain.go @@ -26,10 +26,10 @@ import ( ) var ( - RunE2E bool - KubeConfig string - KubeContext string - StorageClass string + RunE2E bool + KubeConfig string + KubeContext string + ExternalVolumeClass string ) var ( @@ -59,7 +59,7 @@ func bindFlags() { pflag.BoolVar(&NoColor, "no-color", false, "disable colors in output") pflag.StringVar(&KubeConfig, "kube-config", "", "Location of the kubeconfig") pflag.StringVar(&KubeContext, "kube-context", "", "Kubernetes context to use") - pflag.StringVar(&StorageClass, "storage-class", "csi-nfs-sc", "StorageClass to use for external volume tests") + pflag.StringVar(&ExternalVolumeClass, "external-volume-class", "csi-nfs", "ExternalVolumeClass to use for external volume tests") pflag.StringVar(&previewFlag, "preview", "", `Preview gates the install under test enabled, as in ATE_PREVIEW ("ALL" for all, "" for none); required in CI`) } From 9d5549e129efe2a2ca82b9d64919515d3e28cd3d Mon Sep 17 00:00:00 2001 From: Vu Le Date: Wed, 11 Nov 2026 22:05:27 +0000 Subject: [PATCH 22/30] stop creatingk8s StorageClasses in CSI setup Signed-off-by: Vu Le --- cmd/ate-setup/internal/steps/csi.go | 23 ------- cmd/ate-setup/internal/steps/csi_test.go | 61 +++++-------------- hack/csi/nfs-server.yaml | 2 +- hack/setup-csi-nfs-kind.sh | 14 ++--- .../examples/csi-storageclass.yaml | 8 --- .../deploy/example/storageclass-nfs.yaml | 21 ------- 6 files changed, 20 insertions(+), 109 deletions(-) delete mode 100644 hack/third_party/csi-driver-host-path/examples/csi-storageclass.yaml delete mode 100644 hack/third_party/csi-driver-nfs/deploy/example/storageclass-nfs.yaml diff --git a/cmd/ate-setup/internal/steps/csi.go b/cmd/ate-setup/internal/steps/csi.go index 0a2d9e0e24..36dc0bd025 100644 --- a/cmd/ate-setup/internal/steps/csi.go +++ b/cmd/ate-setup/internal/steps/csi.go @@ -185,9 +185,6 @@ func (e *Env) setupCSIHostpath(ctx context.Context) error { if err := e.deleteService(ctx, "default", "csi-hostpath-controller"); err != nil { return err } - if err := e.deleteStorageClass(ctx, "csi-hostpath-sc"); err != nil { - return err - } if err := e.Kube.WaitDeleted(ctx, schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "StatefulSet"}, "default", "csi-hostpathplugin", e.Cfg.RolloutTimeout); err != nil { return err } @@ -252,11 +249,6 @@ spec: return fmt.Errorf("while patching the csi-hostpathplugin StatefulSet: %w", err) } - log.Infof("Creating the csi-hostpath-sc StorageClass...") - if err := e.Kube.ApplyPath(ctx, driverDir+"/examples/csi-storageclass.yaml"); err != nil { - return err - } - log.Infof("Waiting for the CSI hostpath and proxy pods to be ready...") for _, name := range []string{"csi-hostpathplugin", "csi-hostpath-socat"} { if err := e.Kube.RolloutStatus(ctx, kube.KindStatefulSet, "default", name, e.Cfg.WaitTimeout(BootstrapTimeout)); err != nil { @@ -537,13 +529,6 @@ spec: return fmt.Errorf("while patching the csi-nfs-controller Deployment: %w", err) } - // The driver resolves the server's DNS name at provisioning time, so the - // StorageClass can be created before the NFS server has an address. - log.Infof("Creating the csi-nfs-sc StorageClass...") - if err := e.Kube.ApplyPath(ctx, deployDir+"/example/storageclass-nfs.yaml"); err != nil { - return err - } - log.Infof("Waiting for the NFS server and CSI driver to be ready...") if err := e.Kube.RolloutStatus(ctx, kube.KindDeployment, "default", "nfs-server", e.Cfg.WaitTimeout(BootstrapTimeout)); err != nil { return err @@ -592,14 +577,6 @@ func (e *Env) deleteService(ctx context.Context, namespace, name string) error { return nil } -func (e *Env) deleteStorageClass(ctx context.Context, name string) error { - err := e.Kube.Typed.StorageV1().StorageClasses().Delete(ctx, name, metav1.DeleteOptions{}) - if err != nil && !apierrors.IsNotFound(err) { - return fmt.Errorf("while deleting storageclass %s: %w", name, err) - } - return nil -} - // kindNodeName returns the worker node to pin the hostpath driver to, // preferring a non-control-plane node and falling back to the only node on a // single-node cluster. diff --git a/cmd/ate-setup/internal/steps/csi_test.go b/cmd/ate-setup/internal/steps/csi_test.go index a6bd18c6eb..390d860684 100644 --- a/cmd/ate-setup/internal/steps/csi_test.go +++ b/cmd/ate-setup/internal/steps/csi_test.go @@ -129,48 +129,9 @@ func TestTheHostpathControllerServiceIsCreatedBeforeTheDriver(t *testing.T) { } } -// The e2e tests, the demos and the benchmarks all provision from csi-nfs-sc, so -// both NFS setups apply the one manifest that defines it rather than each -// carrying a copy that can drift. The step wants a cluster, so which file it -// applies is pinned in the source. -func TestTheNFSSetupsApplyTheSharedStorageClass(t *testing.T) { - const manifest = "hack/third_party/csi-driver-nfs/deploy/example/storageclass-nfs.yaml" - root := repoRoot(t) - - objs, err := kube.LoadPath(filepath.Join(root, manifest)) - if err != nil { - t.Fatalf("loading %s: %v", manifest, err) - } - if len(objs) != 1 || objs[0].GetKind() != "StorageClass" || objs[0].GetName() != "csi-nfs-sc" { - t.Fatalf("%s holds %d object(s), want only the csi-nfs-sc StorageClass", manifest, len(objs)) - } - if p, _, _ := unstructured.NestedString(objs[0].Object, "provisioner"); p != "nfs.csi.k8s.io" { - t.Errorf("csi-nfs-sc provisioner = %q, want nfs.csi.k8s.io", p) - } - - goSetup := functionBody(t, "csi.go", "func (e *Env) setupCSINFS(") - if !strings.Contains(goSetup, `deployDir+"/example/storageclass-nfs.yaml"`) { - t.Errorf("setupCSINFS no longer applies %s", manifest) - } - script, err := os.ReadFile(filepath.Join(root, "hack", "setup-csi-nfs-kind.sh")) - if err != nil { - t.Fatalf("reading the shell setup: %v", err) - } - if !strings.Contains(string(script), manifest) { - t.Errorf("hack/setup-csi-nfs-kind.sh no longer applies %s", manifest) - } - for name, src := range map[string]string{ - "setupCSINFS": goSetup, - "hack/setup-csi-nfs-kind.sh": string(script), - } { - if strings.Contains(src, "kind: StorageClass") { - t.Errorf("%s defines a StorageClass inline; apply %s instead", name, manifest) - } - } -} - -// Both NFS setups register the canonical csi-nfs ExternalVolumeClass from the -// same checked-in manifest so neither carries an inline copy that can drift. +// The e2e tests, the demos and the benchmarks all provision from csi-nfs, so +// both NFS setups register the one manifest that defines it rather than each +// carrying a copy that can drift. func TestTheNFSSetupsRegisterTheSharedExternalVolumeClass(t *testing.T) { const manifest = "hack/csi/external-volume-class-nfs.yaml" root := repoRoot(t) @@ -193,10 +154,18 @@ func TestTheNFSSetupsRegisterTheSharedExternalVolumeClass(t *testing.T) { t.Errorf("csi-nfs mountOptions = %v, want [nfsvers=4.1]", class.GetMountOptions()) } - goSetup := functionBody(t, "substrate.go", "func externalVolumeClassesForDriver(") - if !strings.Contains(goSetup, `"external-volume-class-nfs.yaml"`) { + goRegister := functionBody(t, "substrate.go", "func externalVolumeClassesForDriver(") + if !strings.Contains(goRegister, `"external-volume-class-nfs.yaml"`) { t.Errorf("externalVolumeClassesForDriver no longer loads %s", manifest) } + for fn, sig := range map[string]string{ + "setupCSINFS": "func (e *Env) setupCSINFS(", + "setupCSIHostpath": "func (e *Env) setupCSIHostpath(", + } { + if strings.Contains(functionBody(t, "csi.go", sig), "StorageClass") { + t.Errorf("%s still references a Kubernetes StorageClass", fn) + } + } script, err := os.ReadFile(filepath.Join(root, "hack", "setup-csi-nfs-kind.sh")) if err != nil { t.Fatalf("reading the shell setup: %v", err) @@ -205,7 +174,7 @@ func TestTheNFSSetupsRegisterTheSharedExternalVolumeClass(t *testing.T) { t.Errorf("hack/setup-csi-nfs-kind.sh no longer registers %s", manifest) } for name, src := range map[string]string{ - "externalVolumeClassesForDriver": goSetup, + "externalVolumeClassesForDriver": goRegister, "hack/setup-csi-nfs-kind.sh": string(script), } { if strings.Contains(src, "\ndriverName:") { @@ -283,7 +252,7 @@ func TestTheNFSShellSetupMatchesTheGoSetup(t *testing.T) { } src := string(script) - for _, forbidden := range []string{"socat:", "privileged: true"} { + for _, forbidden := range []string{"socat:", "privileged: true", "StorageClass"} { if strings.Contains(src, forbidden) { t.Errorf("hack/setup-csi-nfs-kind.sh still contains %q", forbidden) } diff --git a/hack/csi/nfs-server.yaml b/hack/csi/nfs-server.yaml index b894dbbe13..e09edd8c5d 100644 --- a/hack/csi/nfs-server.yaml +++ b/hack/csi/nfs-server.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# The NFS server backing the csi-nfs-sc StorageClass on Kind. Development only. +# The NFS server backing the csi-nfs ExternalVolumeClass on Kind. Development only. --- kind: Service apiVersion: v1 diff --git a/hack/setup-csi-nfs-kind.sh b/hack/setup-csi-nfs-kind.sh index 1b4c307bf0..0eb24151db 100755 --- a/hack/setup-csi-nfs-kind.sh +++ b/hack/setup-csi-nfs-kind.sh @@ -224,19 +224,13 @@ spec: path: trust-bundle.pem ' -# 6. Create NFS StorageClass (pointing to the in-cluster NFS server) -# We wait for the NFS server service to get an IP first, but we can use its DNS name -# since kube-dns should resolve it. The CSI driver will resolve it when provisioning. -echo "Creating csi-nfs-sc StorageClass..." -kubectl apply -f "${ROOT}/hack/third_party/csi-driver-nfs/deploy/example/storageclass-nfs.yaml" - -# 7. Wait for deployments to be ready +# 6. Wait for deployments to be ready echo "Waiting for NFS server and CSI driver to be ready..." kubectl rollout status deployment/nfs-server -n default --timeout=120s kubectl rollout status deployment/csi-nfs-controller -n kube-system --timeout=120s kubectl rollout status daemonset/csi-nfs-node -n kube-system --timeout=120s -# 8. Create the CSIDriverConfig for Substrate +# 7. Create the CSIDriverConfig for Substrate echo "Creating nfs.csi.k8s.io CSIDriverConfig..." cat </dev/null 2>&1 || true diff --git a/hack/third_party/csi-driver-host-path/examples/csi-storageclass.yaml b/hack/third_party/csi-driver-host-path/examples/csi-storageclass.yaml deleted file mode 100644 index d53fcd0e8d..0000000000 --- a/hack/third_party/csi-driver-host-path/examples/csi-storageclass.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: storage.k8s.io/v1 -kind: StorageClass -metadata: - name: csi-hostpath-sc -provisioner: hostpath.csi.k8s.io -reclaimPolicy: Delete -volumeBindingMode: Immediate -allowVolumeExpansion: true diff --git a/hack/third_party/csi-driver-nfs/deploy/example/storageclass-nfs.yaml b/hack/third_party/csi-driver-nfs/deploy/example/storageclass-nfs.yaml deleted file mode 100644 index 8d4a456ce6..0000000000 --- a/hack/third_party/csi-driver-nfs/deploy/example/storageclass-nfs.yaml +++ /dev/null @@ -1,21 +0,0 @@ -# The csi-nfs-sc StorageClass, backed by the dev NFS server in -# hack/csi/nfs-server.yaml. `ate-setup setup csi nfs` and -# hack/setup-csi-nfs-kind.sh both apply this file, so the -# e2e tests, demos and benchmarks all provision from the same class. -# -# Based on deploy/example/storageclass-nfs.yaml from -# kubernetes-csi/csi-driver-nfs, renamed csi-nfs-sc. The share is "/" because -# nfs-server.yaml exports a single directory with fsid=0, which NFSv4 presents -# as the pseudo-root. -apiVersion: storage.k8s.io/v1 -kind: StorageClass -metadata: - name: csi-nfs-sc -provisioner: nfs.csi.k8s.io -parameters: - server: nfs-server.default.svc.cluster.local - share: / -reclaimPolicy: Delete -volumeBindingMode: Immediate -mountOptions: - - nfsvers=4.1 From 7aeab56fde0f5ed5c25bab7cc5d20c15e51127d8 Mon Sep 17 00:00:00 2001 From: Vu Le Date: Thu, 12 Nov 2026 00:25:53 +0000 Subject: [PATCH 23/30] swap remaining volume test templates in functionaltest and workload_spec_test to EVC Signed-off-by: Vu Le --- .../functionaltest/actor_template_test.go | 2 +- .../controlapi/functionaltest/actor_test.go | 85 +++++++++++-------- .../actor_volume_detach_test.go | 5 +- .../external_volume_class_test.go | 13 +++ .../internal/controlapi/workload_spec_test.go | 4 +- 5 files changed, 69 insertions(+), 40 deletions(-) diff --git a/cmd/ateapi/internal/controlapi/functionaltest/actor_template_test.go b/cmd/ateapi/internal/controlapi/functionaltest/actor_template_test.go index 4d8f20a469..880cc9ab3e 100644 --- a/cmd/ateapi/internal/controlapi/functionaltest/actor_template_test.go +++ b/cmd/ateapi/internal/controlapi/functionaltest/actor_template_test.go @@ -407,7 +407,7 @@ func TestCreateActorTemplate_ExternalVolumesPreview(t *testing.T) { }}, Volumes: []*ateapi.Volume{{ Name: "data", - External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{StorageClassName: "standard", CapacityBytes: 1 << 30}}, + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ExternalVolumeClass: &ateapi.ObjectRef{Name: "standard"}, CapacityBytes: 1 << 30}}, }}, Resources: &ateapi.ResourceRequirements{Limits: resources.CPUMemory(1000, 1<<30)}, }, diff --git a/cmd/ateapi/internal/controlapi/functionaltest/actor_test.go b/cmd/ateapi/internal/controlapi/functionaltest/actor_test.go index 1028f4f1d2..9c6d3b5cd0 100644 --- a/cmd/ateapi/internal/controlapi/functionaltest/actor_test.go +++ b/cmd/ateapi/internal/controlapi/functionaltest/actor_test.go @@ -120,13 +120,14 @@ func TestCreateActor_WithExternalVolumes(t *testing.T) { ns := namespaceForTest("ns-create-ext-vols") tc := setupPreviewTest(t, ns) defer tc.cleanup() + seedMockExternalVolumeClass(t, tc, "standard") volumes := []*ateapi.Volume{ { Name: "ext-vol-1", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - StorageClassName: "standard", - CapacityBytes: 10 << 30, + ExternalVolumeClass: &ateapi.ObjectRef{Name: "standard"}, + CapacityBytes: 10 << 30, }}, }, } @@ -183,11 +184,12 @@ func TestCreateActor_ExternalVolumesWithoutOptIn(t *testing.T) { ns := namespaceForTest("ns-create-ext-vols-no-opt-in") tc := setupPreviewTest(t, ns) defer tc.cleanup() + seedMockExternalVolumeClass(t, tc, "standard") createTemplateWithVolumes(t, tc, ns, []*ateapi.Volume{{ Name: "ext-vol-1", - External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{StorageClassName: "standard", CapacityBytes: 10 << 30}}, + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ExternalVolumeClass: &ateapi.ObjectRef{Name: "standard"}, CapacityBytes: 10 << 30}}, }}, []*ateapi.VolumeMount{{Name: "ext-vol-1", MountPath: "/data"}}) @@ -215,11 +217,12 @@ func TestActorLifecycle_ExternalVolumesWithoutOptIn(t *testing.T) { ns := namespaceForTest("ns-lifecycle-ext-vols-no-opt-in") tc := setupPreviewTest(t, ns) defer tc.cleanup() + seedMockExternalVolumeClass(t, tc, "fast") createTemplateWithVolumes(t, tc, ns, []*ateapi.Volume{{ Name: "data-vol", - External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{StorageClassName: "fast", CapacityBytes: 20 << 30}}, + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ExternalVolumeClass: &ateapi.ObjectRef{Name: "fast"}, CapacityBytes: 20 << 30}}, }}, []*ateapi.VolumeMount{{Name: "data-vol", MountPath: "/mnt/data"}}) createWorkerPod(t, tc, ns, "worker-1", "node1", "pool1") @@ -399,6 +402,7 @@ func TestCreateActor_RejectsSnapshotWithExternalVolumes(t *testing.T) { ns := namespaceForTest("ns-snapshot-external-volume") tc := setupPreviewTest(t, ns) defer tc.cleanup() + seedMockExternalVolumeClass(t, tc, "standard") template, err := tc.client.CreateActorTemplate(context.Background(), &ateapi.CreateActorTemplateRequest{ ActorTemplate: &ateapi.ActorTemplate{ Metadata: &ateapi.ResourceMetadata{Atespace: testAtespace, Name: "tmpl1"}, @@ -408,7 +412,7 @@ func TestCreateActor_RejectsSnapshotWithExternalVolumes(t *testing.T) { Volumes: []*ateapi.Volume{{ Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - CapacityBytes: 1 << 30, StorageClassName: "standard", + CapacityBytes: 1 << 30, ExternalVolumeClass: &ateapi.ObjectRef{Name: "standard"}, }}, }}, Resources: &ateapi.ResourceRequirements{Limits: resources.CPUMemory(1000, 512<<20)}, @@ -429,8 +433,8 @@ func TestCreateActor_RejectsSnapshotWithExternalVolumes(t *testing.T) { SourceTag: tagRef, }, }) - if apierror.Code(err) != codes.FailedPrecondition { - t.Fatalf("CreateActor status = %v, want FailedPrecondition", apierror.Code(err)) + if apierror.Code(err) != codes.FailedPrecondition || !strings.Contains(err.Error(), "Tag cloning") { + t.Fatalf("CreateActor err = %v (code %v), want FailedPrecondition mentioning Tag cloning", err, apierror.Code(err)) } } @@ -1325,13 +1329,14 @@ func TestDeleteActor_Running(t *testing.T) { "substrate.io/mock": plugin, }) defer tc.cleanup() + seedMockExternalVolumeClass(t, tc, "standard") createTemplateWithVolumes(t, tc, ns, []*ateapi.Volume{ { Name: "vol1", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - StorageClassName: "standard", - CapacityBytes: 10 << 30, + ExternalVolumeClass: &ateapi.ObjectRef{Name: "standard"}, + CapacityBytes: 10 << 30, }}, }, }, []*ateapi.VolumeMount{ @@ -1879,13 +1884,14 @@ func TestActorLifecycle_WithExternalVolumes(t *testing.T) { ns := namespaceForTest("ns-lifecycle-ext-vols") tc := setupPreviewTest(t, ns) defer tc.cleanup() + seedMockExternalVolumeClass(t, tc, "fast") volumes := []*ateapi.Volume{ { Name: "data-vol", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - StorageClassName: "fast", - CapacityBytes: 20 << 30, + ExternalVolumeClass: &ateapi.ObjectRef{Name: "fast"}, + CapacityBytes: 20 << 30, }}, }, } @@ -2179,20 +2185,21 @@ func TestResumeActor_VolumeCreationFailure(t *testing.T) { "substrate.io/mock": plugin, }) defer tc.cleanup() + seedMockExternalVolumeClass(t, tc, "standard") volumes := []*ateapi.Volume{ { Name: "succ-vol1", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - StorageClassName: "standard", - CapacityBytes: 10 << 30, + ExternalVolumeClass: &ateapi.ObjectRef{Name: "standard"}, + CapacityBytes: 10 << 30, }}, }, { Name: "fail-vol2", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - StorageClassName: "standard", - CapacityBytes: 10 << 30, + ExternalVolumeClass: &ateapi.ObjectRef{Name: "standard"}, + CapacityBytes: 10 << 30, }}, }, } @@ -2323,20 +2330,21 @@ func TestResumeActor_VolumeCreationRetrySuccess(t *testing.T) { "substrate.io/mock": plugin, }) defer tc.cleanup() + seedMockExternalVolumeClass(t, tc, "standard") volumes := []*ateapi.Volume{ { Name: "succ-vol1", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - StorageClassName: "standard", - CapacityBytes: 10 << 30, + ExternalVolumeClass: &ateapi.ObjectRef{Name: "standard"}, + CapacityBytes: 10 << 30, }}, }, { Name: "retry-vol2", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - StorageClassName: "standard", - CapacityBytes: 10 << 30, + ExternalVolumeClass: &ateapi.ObjectRef{Name: "standard"}, + CapacityBytes: 10 << 30, }}, }, } @@ -2484,13 +2492,14 @@ func TestResumeActor_VolumeAttachFailureAndRetry(t *testing.T) { "substrate.io/mock": plugin, }) defer tc.cleanup() + seedMockExternalVolumeClass(t, tc, "standard") volumes := []*ateapi.Volume{ { Name: "vol1", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - StorageClassName: "standard", - CapacityBytes: 10 << 30, + ExternalVolumeClass: &ateapi.ObjectRef{Name: "standard"}, + CapacityBytes: 10 << 30, }}, }, } @@ -2587,13 +2596,14 @@ func TestResumeActor_VolumeAttachFailure_DeleteActor(t *testing.T) { "substrate.io/mock": plugin, }) defer tc.cleanup() + seedMockExternalVolumeClass(t, tc, "standard") volumes := []*ateapi.Volume{ { Name: "vol1", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - StorageClassName: "standard", - CapacityBytes: 10 << 30, + ExternalVolumeClass: &ateapi.ObjectRef{Name: "standard"}, + CapacityBytes: 10 << 30, }}, }, } @@ -2736,21 +2746,22 @@ func TestResumeActor_MultiVolumePartialAttachFailure_Retry(t *testing.T) { "substrate.io/mock": plugin, }) defer tc.cleanup() + seedMockExternalVolumeClass(t, tc, "standard") // 1. Create a template with two external volumes and a worker pod. volumes := []*ateapi.Volume{ { Name: "vol1", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - StorageClassName: "standard", - CapacityBytes: 10 << 30, + ExternalVolumeClass: &ateapi.ObjectRef{Name: "standard"}, + CapacityBytes: 10 << 30, }}, }, { Name: "vol2", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - StorageClassName: "standard", - CapacityBytes: 10 << 30, + ExternalVolumeClass: &ateapi.ObjectRef{Name: "standard"}, + CapacityBytes: 10 << 30, }}, }, } @@ -2908,14 +2919,15 @@ func TestSuspendActor_VolumeDetachFailure_RetrySuccess(t *testing.T) { "substrate.io/mock": plugin, }) defer tc.cleanup() + seedMockExternalVolumeClass(t, tc, "standard") // 1. Create template with external volume and a mock worker pod. volumes := []*ateapi.Volume{ { Name: "vol1", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - StorageClassName: "standard", - CapacityBytes: 10 << 30, + ExternalVolumeClass: &ateapi.ObjectRef{Name: "standard"}, + CapacityBytes: 10 << 30, }}, }, } @@ -3018,14 +3030,15 @@ func TestSuspendActor_VolumeDetachFailure_DeleteActor(t *testing.T) { "substrate.io/mock": plugin, }) defer tc.cleanup() + seedMockExternalVolumeClass(t, tc, "standard") // 1. Create template with external volume and a mock worker pod. volumes := []*ateapi.Volume{ { Name: "vol1", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - StorageClassName: "standard", - CapacityBytes: 10 << 30, + ExternalVolumeClass: &ateapi.ObjectRef{Name: "standard"}, + CapacityBytes: 10 << 30, }}, }, } @@ -3109,14 +3122,15 @@ func TestSuspendActorAsync_VolumeLifecycle_DetachResumeAndMigrate(t *testing.T) "substrate.io/mock": plugin, }) defer tc.cleanup() + seedMockExternalVolumeClass(t, tc, "standard") // 1. Create template with external volume and a mock worker pod. volumes := []*ateapi.Volume{ { Name: "vol1", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - StorageClassName: "standard", - CapacityBytes: 10 << 30, + ExternalVolumeClass: &ateapi.ObjectRef{Name: "standard"}, + CapacityBytes: 10 << 30, }}, }, } @@ -3299,14 +3313,15 @@ func TestSuspendActorAsync_VolumeDetachFailure_RetrySuccess(t *testing.T) { "substrate.io/mock": plugin, }) defer tc.cleanup() + seedMockExternalVolumeClass(t, tc, "standard") // 1. Create template with external volume and a mock worker pod. volumes := []*ateapi.Volume{ { Name: "vol1", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - StorageClassName: "standard", - CapacityBytes: 10 << 30, + ExternalVolumeClass: &ateapi.ObjectRef{Name: "standard"}, + CapacityBytes: 10 << 30, }}, }, } diff --git a/cmd/ateapi/internal/controlapi/functionaltest/actor_volume_detach_test.go b/cmd/ateapi/internal/controlapi/functionaltest/actor_volume_detach_test.go index b2d615f26a..0d233dbc28 100644 --- a/cmd/ateapi/internal/controlapi/functionaltest/actor_volume_detach_test.go +++ b/cmd/ateapi/internal/controlapi/functionaltest/actor_volume_detach_test.go @@ -66,11 +66,12 @@ func assertDetachedNodes(t *testing.T, plugin *attachFailVolumePlugin, step stri func createSingleVolumeActor(t *testing.T, tc *testContext, ns, name string) string { t.Helper() preview.InitForTest(t, "ExternalVolumes") + seedMockExternalVolumeClass(t, tc, "standard") volumes := []*ateapi.Volume{{ Name: "vol1", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - StorageClassName: "standard", - CapacityBytes: 10 << 30, + ExternalVolumeClass: &ateapi.ObjectRef{Name: "standard"}, + CapacityBytes: 10 << 30, }}, }} mounts := []*ateapi.VolumeMount{{Name: "vol1", MountPath: "/mnt/vol1"}} diff --git a/cmd/ateapi/internal/controlapi/functionaltest/external_volume_class_test.go b/cmd/ateapi/internal/controlapi/functionaltest/external_volume_class_test.go index db9e1cbec0..04aefbde35 100644 --- a/cmd/ateapi/internal/controlapi/functionaltest/external_volume_class_test.go +++ b/cmd/ateapi/internal/controlapi/functionaltest/external_volume_class_test.go @@ -22,6 +22,7 @@ import ( "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/preview" "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "google.golang.org/protobuf/testing/protocmp" ) @@ -42,6 +43,18 @@ func createExternalVolumeClass(t *testing.T, tc *testContext, name string) *atea return created } +func seedMockExternalVolumeClass(t *testing.T, tc *testContext, name string) { + t.Helper() + if _, err := tc.client.CreateExternalVolumeClass(context.Background(), &ateapi.CreateExternalVolumeClassRequest{ + ExternalVolumeClass: &ateapi.ExternalVolumeClass{ + Metadata: &ateapi.ResourceMetadata{Name: name}, + DriverName: "substrate.io/mock", + }, + }); err != nil && status.Code(err) != codes.AlreadyExists { + t.Fatalf("CreateExternalVolumeClass(%s) failed: %v", name, err) + } +} + func TestCreateExternalVolumeClass(t *testing.T) { preview.InitForTest(t, "ExternalVolumes") ns := namespaceForTest("ns-create-evc") diff --git a/cmd/ateapi/internal/controlapi/workload_spec_test.go b/cmd/ateapi/internal/controlapi/workload_spec_test.go index 9b69df2e9d..4b151a75ae 100644 --- a/cmd/ateapi/internal/controlapi/workload_spec_test.go +++ b/cmd/ateapi/internal/controlapi/workload_spec_test.go @@ -392,7 +392,7 @@ func TestAppendExternalVolumes(t *testing.T) { { Name: "vol-1", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - StorageClassName: "pd-standard", + ExternalVolumeClass: &ateapi.ObjectRef{Name: "pd-standard"}, }}, }, { @@ -402,7 +402,7 @@ func TestAppendExternalVolumes(t *testing.T) { { Name: "unmounted-vol", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - StorageClassName: "pd-standard", + ExternalVolumeClass: &ateapi.ObjectRef{Name: "pd-standard"}, }}, }, }, From c55d44549605602bc234e9a152742e18a2fed98b Mon Sep 17 00:00:00 2001 From: Vu Le Date: Thu, 12 Nov 2026 00:26:25 +0000 Subject: [PATCH 24/30] remove StorageClass provisioning branch, informer, lister, and ClusterRole RBAC from ateapi Signed-off-by: Vu Le --- .../internal/controlapi/access_policy_test.go | 2 +- cmd/ateapi/internal/controlapi/actor.go | 2 +- .../controlapi/actor_template_test.go | 10 +- cmd/ateapi/internal/controlapi/actor_test.go | 12 +- .../internal/controlapi/atespace_test.go | 2 +- .../controlapi/functionaltest/common_test.go | 6 - .../controlapi/functionaltest/main_test.go | 17 -- cmd/ateapi/internal/controlapi/service.go | 12 +- .../controlapi/snapshot_report_test.go | 2 +- cmd/ateapi/internal/controlapi/tag_test.go | 10 +- .../controlapi/template_reconciler_test.go | 4 +- cmd/ateapi/internal/controlapi/volumes.go | 75 +++--- .../internal/controlapi/volumes_test.go | 224 +++++++----------- cmd/ateapi/internal/controlapi/worker_test.go | 6 +- cmd/ateapi/internal/controlapi/workflow.go | 4 - .../controlapi/workflow_delete_test.go | 4 +- .../internal/controlapi/workflow_resume.go | 2 +- .../controlapi/workflow_resume_test.go | 18 +- .../controlapi/workflow_testutil_test.go | 2 +- cmd/ateapi/main.go | 6 - manifests/ate-install/ate-api-server.yaml | 2 + 21 files changed, 155 insertions(+), 267 deletions(-) diff --git a/cmd/ateapi/internal/controlapi/access_policy_test.go b/cmd/ateapi/internal/controlapi/access_policy_test.go index 900c98eb12..1741397958 100644 --- a/cmd/ateapi/internal/controlapi/access_policy_test.go +++ b/cmd/ateapi/internal/controlapi/access_policy_test.go @@ -48,7 +48,7 @@ func TestAccessPolicy_GlobalAndAtespaceGovernance(t *testing.T) { } persistence.SetPolicyManager(policyManager) - svc := NewRPCService(persistence, nil, nil, nil, nil, nil, "", nil, nil, "", nil, "") + svc := NewRPCService(persistence, nil, nil, nil, nil, "", nil, nil, "", nil, "") interceptor := authz.UnaryServerInterceptor(authorizer) userCtx := func(id string) context.Context { diff --git a/cmd/ateapi/internal/controlapi/actor.go b/cmd/ateapi/internal/controlapi/actor.go index d9f6c557a1..abf9d6ce3d 100644 --- a/cmd/ateapi/internal/controlapi/actor.go +++ b/cmd/ateapi/internal/controlapi/actor.go @@ -109,7 +109,7 @@ func (s *ServiceImpl) CreateActor(ctx context.Context, inActor *ateapi.Actor) (* // Volume creation is completed asynchronously after the actor is recorded. var initVols []*ateapi.ExternalVolumeStatus - if iv, err := initialExternalVolumes(ctx, s, s.storageClassLister, template); err != nil { + if iv, err := initialExternalVolumes(ctx, s, template); err != nil { return nil, err } else if preview.IsEnabledFor(ctx, preview.GateExternalVolumes) { initVols = iv diff --git a/cmd/ateapi/internal/controlapi/actor_template_test.go b/cmd/ateapi/internal/controlapi/actor_template_test.go index 66aa77778a..cd7de8bf6b 100644 --- a/cmd/ateapi/internal/controlapi/actor_template_test.go +++ b/cmd/ateapi/internal/controlapi/actor_template_test.go @@ -56,7 +56,7 @@ func validActorTemplate(mutations ...func(*ateapi.ActorTemplate)) *ateapi.ActorT // while the atespace is missing, and succeeds once the atespace exists. func TestCreateActorTemplate(t *testing.T) { persistence := newTestPersistence(t) - impl := newServiceImpl(persistence, nil) + impl := newServiceImpl(persistence) impl.clusterSnapshotLocation = "gs://cluster-bucket/" s := &RPCService{impl: impl} ctx := context.Background() @@ -125,7 +125,7 @@ func TestCreateActorTemplate_RequiresSnapshotLocation(t *testing.T) { t.Run(tt.name, func(t *testing.T) { preview.InitForTest(t, tt.gates...) persistence := newTestPersistence(t) - impl := newServiceImpl(persistence, nil) + impl := newServiceImpl(persistence) impl.clusterSnapshotLocation = tt.clusterSnapshotLocation s := &RPCService{impl: impl} ctx := context.Background() @@ -152,7 +152,7 @@ func TestCreateActorTemplate_RequiresSnapshotLocation(t *testing.T) { // the only guard. func TestCreateActorTemplateIgnoresServerOwnedFields(t *testing.T) { persistence := newTestPersistence(t) - impl := newServiceImpl(persistence, nil) + impl := newServiceImpl(persistence) impl.clusterSnapshotLocation = "gs://cluster-bucket/" s := &RPCService{impl: impl} ctx := context.Background() @@ -199,7 +199,7 @@ func TestCreateActorTemplateIgnoresServerOwnedFields(t *testing.T) { // snapshot_config is optional: create fills an omitted one with every default. func TestCreateActorTemplateDefaultsOmittedSnapshotConfig(t *testing.T) { persistence := newTestPersistence(t) - impl := newServiceImpl(persistence, nil) + impl := newServiceImpl(persistence) impl.clusterSnapshotLocation = "gs://cluster-bucket/" s := &RPCService{impl: impl} ctx := context.Background() @@ -276,7 +276,7 @@ func TestDeleteActorTemplate(t *testing.T) { tagRef := resources.TagRefFromTag(tag) tagURI := mustReservedTagSnapshotURI(t, tag) objects.PutSnapshot(t, tagURI, "manifest.json") - svc := &RPCService{impl: newServiceImpl(persistence, nil), actorWorkflow: workflow, objectStorePlugin: objectstoreplugintest.ControlClient(objects)} + svc := &RPCService{impl: newServiceImpl(persistence), actorWorkflow: workflow, objectStorePlugin: objectstoreplugintest.ControlClient(objects)} // The handler must clean up an active golden actor. mustUpdateActorStatus(t, ctx, persistence, actor, func(s *ateapi.ActorStatus) { s.State = ateapi.ActorState_ACTOR_STATE_RUNNING diff --git a/cmd/ateapi/internal/controlapi/actor_test.go b/cmd/ateapi/internal/controlapi/actor_test.go index 4787e0f2d5..9e42f064e2 100644 --- a/cmd/ateapi/internal/controlapi/actor_test.go +++ b/cmd/ateapi/internal/controlapi/actor_test.go @@ -306,7 +306,7 @@ func TestUpdateActor_RepointTemplate(t *testing.T) { ActorTemplate: &ateapi.ObjectRef{Atespace: testAtespace, Name: "tmpl-a"}, Status: &ateapi.ActorStatus{State: ateapi.ActorState_ACTOR_STATE_SUSPENDED}, }) - svc := &RPCService{impl: newServiceImpl(persistence, nil)} + svc := &RPCService{impl: newServiceImpl(persistence)} // Repointing at a template that does not exist is rejected. _, err := svc.UpdateActor(ctx, &ateapi.UpdateActorRequest{Actor: &ateapi.Actor{ @@ -595,7 +595,7 @@ func TestUpdateActor_RepointTemplateStorageLocation(t *testing.T) { if tt.gateOff { preview.InitForTest(t) } - impl := newServiceImpl(persistence, nil) + impl := newServiceImpl(persistence) impl.clusterSnapshotLocation = tt.clusterSnapshotLocation svc := &RPCService{impl: impl} actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ @@ -787,7 +787,7 @@ func TestUpdateActor_DeleteRecreateRace(t *testing.T) { } }, } - svc := &RPCService{impl: newServiceImpl(racing, nil)} + svc := &RPCService{impl: newServiceImpl(racing)} // The client asserts "only update the actor with uid A". original.WorkerSelector = &ateapi.Selector{MatchLabels: map[string]string{"tier": "paid"}} @@ -848,7 +848,7 @@ func TestUpdateActor_ConcurrentDisjointUpdates(t *testing.T) { } }, } - svc := &RPCService{impl: newServiceImpl(racing, nil)} + svc := &RPCService{impl: newServiceImpl(racing)} // Update operation is changing the worker_selector field, not the actor's state (like the concurrent op) // This update must fail: the racing update bumped the version. @@ -904,7 +904,7 @@ func rpcServiceWithActor(t *testing.T, actor *ateapi.Actor) (*RPCService, *ateap t.Cleanup(cleanup) created := storetest.MustCreateActor(t, context.Background(), persistence, actor) - return &RPCService{impl: newServiceImpl(persistence, nil)}, created + return &RPCService{impl: newServiceImpl(persistence)}, created } func TestCreateActor_DoesNotInheritGoldenEgressPolicy(t *testing.T) { @@ -922,7 +922,7 @@ func TestCreateActor_DoesNotInheritGoldenEgressPolicy(t *testing.T) { t.Run(tt.name, func(t *testing.T) { ctx := t.Context() persistence := newTestPersistence(t) - impl := newServiceImpl(persistence, nil) + impl := newServiceImpl(persistence) impl.clusterSnapshotLocation = "gs://cluster-bucket/" svc := &RPCService{impl: impl} storetest.MustCreateAtespace(t, ctx, persistence, "templates") diff --git a/cmd/ateapi/internal/controlapi/atespace_test.go b/cmd/ateapi/internal/controlapi/atespace_test.go index ad6296de2c..c094bb01e5 100644 --- a/cmd/ateapi/internal/controlapi/atespace_test.go +++ b/cmd/ateapi/internal/controlapi/atespace_test.go @@ -71,7 +71,7 @@ func TestAtespace_EndToEndOpenFGAScenarios(t *testing.T) { storeID := storesResp.GetStores()[0].GetId() svc := &RPCService{ - impl: newServiceImpl(persistence, nil), + impl: newServiceImpl(persistence), } interceptor := authz.UnaryServerInterceptor(authorizer) diff --git a/cmd/ateapi/internal/controlapi/functionaltest/common_test.go b/cmd/ateapi/internal/controlapi/functionaltest/common_test.go index 72709ef72d..886db9bf98 100644 --- a/cmd/ateapi/internal/controlapi/functionaltest/common_test.go +++ b/cmd/ateapi/internal/controlapi/functionaltest/common_test.go @@ -53,7 +53,6 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/client-go/informers" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/cache" "k8s.io/utils/ptr" @@ -156,8 +155,6 @@ func setupTestWithOptions(t *testing.T, ns string, options testOptions) *testCon // 3. Initialize Informers ateletFactory, ateletInformer := controlapi.AteletInformer(k8sClient, installdefaults.SystemNamespace) - scFactory := informers.NewSharedInformerFactory(k8sClient, 0) - scLister := scFactory.Storage().V1().StorageClasses().Lister() substrateInformerFactory := externalversions.NewSharedInformerFactory(substrateClient, 0) csiDriverConfigLister := substrateInformerFactory.Ate().V1().CSIDriverConfigs().Lister() @@ -166,11 +163,9 @@ func setupTestWithOptions(t *testing.T, ns string, options testOptions) *testCon ateletFactory.Start(ctx.Done()) substrateInformerFactory.Start(ctx.Done()) - scFactory.Start(ctx.Done()) ateletFactory.WaitForCacheSync(ctx.Done()) substrateInformerFactory.WaitForCacheSync(ctx.Done()) - scFactory.WaitForCacheSync(ctx.Done()) // 4. Initialize Service wc := workercache.New(persistence, 5*time.Minute) @@ -224,7 +219,6 @@ func setupTestWithOptions(t *testing.T, ns string, options testOptions) *testCon persistence, wc, csiDriverConfigLister, - scLister, dialer, instruments, "", diff --git a/cmd/ateapi/internal/controlapi/functionaltest/main_test.go b/cmd/ateapi/internal/controlapi/functionaltest/main_test.go index 1ed69cd759..948907f072 100644 --- a/cmd/ateapi/internal/controlapi/functionaltest/main_test.go +++ b/cmd/ateapi/internal/controlapi/functionaltest/main_test.go @@ -34,7 +34,6 @@ import ( "google.golang.org/grpc" "google.golang.org/protobuf/proto" corev1 "k8s.io/api/core/v1" - storagev1 "k8s.io/api/storage/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" @@ -65,22 +64,6 @@ func TestMain(m *testing.M) { log.Fatalf("create ate-system namespace: %v", err) } - // Create StorageClasses for volume tests - _, err = k8sClient.StorageV1().StorageClasses().Create(context.Background(), &storagev1.StorageClass{ - ObjectMeta: metav1.ObjectMeta{Name: "standard"}, - Provisioner: "substrate.io/mock", - }, metav1.CreateOptions{}) - if err != nil && !apierrors.IsAlreadyExists(err) { - log.Fatalf("create standard storage class: %v", err) - } - _, err = k8sClient.StorageV1().StorageClasses().Create(context.Background(), &storagev1.StorageClass{ - ObjectMeta: metav1.ObjectMeta{Name: "fast"}, - Provisioner: "substrate.io/mock", - }, metav1.CreateOptions{}) - if err != nil && !apierrors.IsAlreadyExists(err) { - log.Fatalf("create fast storage class: %v", err) - } - // Create shared Atelet Pod. Tests that place workers on another node add // their own atelet there via setupAteletOnNode. if err := createAteletPod(k8sClient, "atelet-shared", "node1"); err != nil { diff --git a/cmd/ateapi/internal/controlapi/service.go b/cmd/ateapi/internal/controlapi/service.go index b3ee8de2e6..9db8cc5e88 100644 --- a/cmd/ateapi/internal/controlapi/service.go +++ b/cmd/ateapi/internal/controlapi/service.go @@ -27,7 +27,6 @@ import ( "go.ate.dev/substrate/internal/volume" "go.ate.dev/substrate/internal/volume/csi" atelisters "go.ate.dev/substrate/pkg/client/listers/ate/v1" - storagev1listers "k8s.io/client-go/listers/storage/v1" ) // RPCService implements ateapi.ControlServer and provides the implementation of @@ -77,7 +76,6 @@ func NewRPCService( persistence store.Interface, workerCache *workercache.Cache, csiDriverConfigLister atelisters.CSIDriverConfigLister, - storageClassLister storagev1listers.StorageClassLister, dialer *AteletDialer, instruments *Instruments, egressGatewayAddress string, @@ -87,7 +85,7 @@ func NewRPCService( actorIDJWTPool localjwtauthority.Pool, snapshotLocation string, ) *RPCService { - impl := newServiceImpl(persistence, storageClassLister) + impl := newServiceImpl(persistence) impl.clusterSnapshotLocation = snapshotLocation s := &RPCService{ impl: impl, @@ -101,7 +99,7 @@ func NewRPCService( actorJWTIssuer: actorJWTIssuer, actorIDJWTPool: actorIDJWTPool, } - s.actorWorkflow = NewActorWorkflow(impl, workerCache, dialer, storageClassLister, instruments, egressGatewayAddress, s, objectStorePlugin) + s.actorWorkflow = NewActorWorkflow(impl, workerCache, dialer, instruments, egressGatewayAddress, s, objectStorePlugin) s.actorWorkflow.clusterSnapshotLocation = snapshotLocation s.workerWorkflow = NewWorkerWorkflow(impl, dialer) return s @@ -179,8 +177,6 @@ type ServiceImpl struct { // methods we need to trap. store store.Interface - storageClassLister storagev1listers.StorageClassLister - // clusterSnapshotLocation is ate-api-server's --snapshot-location; see // resolveSnapshotLocation. clusterSnapshotLocation string @@ -192,11 +188,9 @@ var _ store.Interface = (*ServiceImpl)(nil) // implementation layer. func newServiceImpl( persistence store.Interface, - storageClassLister storagev1listers.StorageClassLister, ) *ServiceImpl { s := &ServiceImpl{ - store: persistence, - storageClassLister: storageClassLister, + store: persistence, } return s } diff --git a/cmd/ateapi/internal/controlapi/snapshot_report_test.go b/cmd/ateapi/internal/controlapi/snapshot_report_test.go index 1c3e098793..aa7462e6b5 100644 --- a/cmd/ateapi/internal/controlapi/snapshot_report_test.go +++ b/cmd/ateapi/internal/controlapi/snapshot_report_test.go @@ -413,7 +413,7 @@ func TestApplyLatestDurableLogsStaleReports(t *testing.T) { func TestApplyReportedSnapshotState(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) - w := NewActorWorkflow(persistence, nil, nil, nil, nil, "", nil, nil) + w := NewActorWorkflow(persistence, nil, nil, nil, "", nil, nil) tmpl, err := persistence.CreateActorTemplate(ctx, &ateapi.ActorTemplate{ Metadata: &ateapi.ResourceMetadata{Atespace: reportAtespace, Name: "tmpl"}, SnapshotConfig: &ateapi.SnapshotConfig{StorageLocation: testStorageLocation}, diff --git a/cmd/ateapi/internal/controlapi/tag_test.go b/cmd/ateapi/internal/controlapi/tag_test.go index 4bc06d75d5..00da03f409 100644 --- a/cmd/ateapi/internal/controlapi/tag_test.go +++ b/cmd/ateapi/internal/controlapi/tag_test.go @@ -35,7 +35,7 @@ func TestListTags(t *testing.T) { ctx := context.Background() persistence, cleanup := storetest.SetupTestStore(t) t.Cleanup(cleanup) - svc := &RPCService{impl: newServiceImpl(persistence, nil)} + svc := &RPCService{impl: newServiceImpl(persistence)} const otherAtespace = "other-atespace" seedTag := func(atespace, name string) { @@ -301,7 +301,7 @@ func rpcServiceWithTag(t *testing.T, tag *ateapi.Tag) (*RPCService, *ateapi.Tag) seeded := newTestTag(t, name, actor) seeded.Scope = tag.GetScope() created := storetest.MustCreateTag(t, ctx, persistence, seeded) - return &RPCService{impl: newServiceImpl(persistence, nil)}, created + return &RPCService{impl: newServiceImpl(persistence)}, created } // TestUpdateTag_DeleteRecreateRace checks that an update is not @@ -334,7 +334,7 @@ func TestUpdateTag_DeleteRecreateRace(t *testing.T) { recreatedTag = storetest.MustCreateTag(t, ctx, persistence, newTestTag(t, tagName, actorTwo)) }, } - svc := &RPCService{impl: newServiceImpl(racing, nil)} + svc := &RPCService{impl: newServiceImpl(racing)} // The client asserts "only update the tag with uid A". Its version guard is // satisfied by B as well, because re-tagging resets the version to 1: the @@ -386,7 +386,7 @@ func TestUpdateTag_ConcurrentUpdate(t *testing.T) { } }, } - svc := &RPCService{impl: newServiceImpl(racing, nil)} + svc := &RPCService{impl: newServiceImpl(racing)} originalTag.Scope = ateapi.TagScope_TAG_SCOPE_PUBLISHED _, err := svc.UpdateTag(ctx, &ateapi.UpdateTagRequest{ @@ -417,7 +417,7 @@ func TestUpdateTag_PendingTag(t *testing.T) { ctx := context.Background() persistence, cleanup := storetest.SetupTestStore(t) t.Cleanup(cleanup) - svc := &RPCService{impl: newServiceImpl(persistence, nil)} + svc := &RPCService{impl: newServiceImpl(persistence)} actor := newTestSuspendedActor(t, ctx, persistence, testAtespace, "actor-1") tag := storetest.MustCreateTag(t, ctx, persistence, newPendingTestTag(t, "v1", actor)) diff --git a/cmd/ateapi/internal/controlapi/template_reconciler_test.go b/cmd/ateapi/internal/controlapi/template_reconciler_test.go index aea76020c7..7448733015 100644 --- a/cmd/ateapi/internal/controlapi/template_reconciler_test.go +++ b/cmd/ateapi/internal/controlapi/template_reconciler_test.go @@ -699,7 +699,7 @@ func TestReconcileOne_GoldenEgressPolicyBeforeResume(t *testing.T) { t.Run(tt.name, func(t *testing.T) { ctx := t.Context() persistence := newTestPersistence(t) - impl := newServiceImpl(persistence, nil) + impl := newServiceImpl(persistence) impl.clusterSnapshotLocation = "gs://cluster-bucket/" svc := &RPCService{impl: impl} storetest.MustCreateAtespace(t, ctx, persistence, "templates") @@ -754,7 +754,7 @@ func TestReconcileOne_GoldenEgressPolicyRecovery(t *testing.T) { t.Run(scenario, func(t *testing.T) { ctx := t.Context() persistence := newTestPersistence(t) - impl := newServiceImpl(persistence, nil) + impl := newServiceImpl(persistence) impl.clusterSnapshotLocation = "gs://cluster-bucket/" svc := &RPCService{impl: impl} storetest.MustCreateAtespace(t, ctx, persistence, "templates") diff --git a/cmd/ateapi/internal/controlapi/volumes.go b/cmd/ateapi/internal/controlapi/volumes.go index f75d6736de..b68f00d6e4 100644 --- a/cmd/ateapi/internal/controlapi/volumes.go +++ b/cmd/ateapi/internal/controlapi/volumes.go @@ -25,8 +25,6 @@ import ( "go.ate.dev/substrate/internal/volume" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - k8serrors "k8s.io/apimachinery/pkg/api/errors" - storagev1listers "k8s.io/client-go/listers/storage/v1" ) // externalVolumesStatus wraps vols for ActorStatus, leaving the field unset @@ -44,67 +42,54 @@ type externalVolumeClassGetter interface { GetExternalVolumeClass(ctx context.Context, name string) (*ateapi.ExternalVolumeClass, error) } -// volumeClass is what an external volume template resolves to: the CSI driver, -// the parameters for its CreateVolume call, its mount options, and a label -// that names the class in errors. +// volumeClass holds the resolved ExternalVolumeClass fields for an external +// volume template. type volumeClass struct { + name string driver string params map[string]string mountOptions []string - label string } -// resolveVolumeClass resolves the class of an external volume template from -// external_volume_class when it is set, otherwise from the Kubernetes -// StorageClass named by storage_class_name. -func resolveVolumeClass(ctx context.Context, classes externalVolumeClassGetter, scLister storagev1listers.StorageClassLister, tmpl *ateapi.ExternalVolumeTemplate) (volumeClass, error) { - if ref := tmpl.GetExternalVolumeClass(); ref != nil { - driver, params, mountOptions, err := resolveExternalVolumeClass(ctx, classes, ref) - if err != nil { - return volumeClass{}, err - } - return volumeClass{driver: driver, params: params, mountOptions: mountOptions, label: fmt.Sprintf("ExternalVolumeClass %q", ref.GetName())}, nil - } - - scName := tmpl.GetStorageClassName() - if scName == "" { - return volumeClass{}, apierror.FailedPrecondition("external volume template sets neither external_volume_class nor storage_class_name") - } - sc, err := scLister.Get(scName) - if err != nil { - if k8serrors.IsNotFound(err) { - return volumeClass{}, apierror.FailedPrecondition("StorageClass %q not found", scName) +// resolveVolumeClass resolves the ExternalVolumeClass of an external volume +// template. A missing class is a FailedPrecondition (the template is valid, +// while the class does not exist yet or was deleted), as is a stored template +// from before storage_class_name was retired so the caller knows to recreate +// the template. +func resolveVolumeClass(ctx context.Context, classes externalVolumeClassGetter, tmpl *ateapi.ExternalVolumeTemplate) (volumeClass, error) { + ref := tmpl.GetExternalVolumeClass() + if ref == nil { + if scName := tmpl.GetStorageClassName(); scName != "" { //nolint:staticcheck // SA1019: stored 1.0 preview templates may still carry storage_class_name + return volumeClass{}, apierror.FailedPrecondition("external volume template uses unsupported storage_class_name %q; recreate the template with external_volume_class", scName) } - return volumeClass{}, apierror.Internal("failed to get StorageClass %q: %v", scName, err) + return volumeClass{}, apierror.FailedPrecondition("external volume template does not set external_volume_class") } - return volumeClass{driver: sc.Provisioner, params: sc.Parameters, mountOptions: sc.MountOptions, label: fmt.Sprintf("StorageClass %q", scName)}, nil -} - -// resolveExternalVolumeClass returns the driver, CreateVolume parameters, and -// mount options of the ExternalVolumeClass that ref names. A missing class is a -// FailedPrecondition: the template is valid, but the class it names does not -// exist yet or was deleted. -func resolveExternalVolumeClass(ctx context.Context, classes externalVolumeClassGetter, ref *ateapi.ObjectRef) (driver string, params map[string]string, mountOptions []string, err error) { - class, err := classes.GetExternalVolumeClass(ctx, ref.GetName()) + name := ref.GetName() + class, err := classes.GetExternalVolumeClass(ctx, name) if err != nil { if apierror.Code(err) == codes.NotFound { - return "", nil, nil, apierror.FailedPrecondition("ExternalVolumeClass %q not found", ref.GetName()) + return volumeClass{}, apierror.FailedPrecondition("ExternalVolumeClass %q not found", name) } - return "", nil, nil, apierror.Internal("failed to get ExternalVolumeClass %q: %v", ref.GetName(), err) + return volumeClass{}, apierror.Internal("failed to get ExternalVolumeClass %q: %v", name, err) } - return class.GetDriverName(), class.GetParameters(), class.GetMountOptions(), nil + return volumeClass{ + name: name, + driver: class.GetDriverName(), + params: class.GetParameters(), + mountOptions: class.GetMountOptions(), + }, nil } // initialExternalVolumes constructs the actor's volume objects before volume // creation. A volume has no storage volume ID until it is provisioned. -func initialExternalVolumes(ctx context.Context, classes externalVolumeClassGetter, scLister storagev1listers.StorageClassLister, template *ateapi.ActorTemplate) ([]*ateapi.ExternalVolumeStatus, error) { +func initialExternalVolumes(ctx context.Context, classes externalVolumeClassGetter, template *ateapi.ActorTemplate) ([]*ateapi.ExternalVolumeStatus, error) { if template == nil { return nil, apierror.InvalidArgument("template is required") } var volumes []*ateapi.ExternalVolumeStatus for _, vol := range template.GetVolumes() { if ext := vol.GetExternal().GetTemplate(); ext != nil { - class, err := resolveVolumeClass(ctx, classes, scLister, ext) + class, err := resolveVolumeClass(ctx, classes, ext) if err != nil { return nil, err } @@ -122,7 +107,7 @@ func initialExternalVolumes(ctx context.Context, classes externalVolumeClassGett // createActorVolumes provisions the external volumes in volumesToCreate that have no storage volume ID, using the provided volume plugin. // It returns the list of external volumes (with storage IDs), or an error if any creation fails. // Any volumes processed before or during a failure are returned alongside the error so they can be persisted on the actor. -func createActorVolumes(ctx context.Context, registry VolumePluginRegistry, classes externalVolumeClassGetter, scLister storagev1listers.StorageClassLister, actorUID string, template *ateapi.ActorTemplate, volumesToCreate []*ateapi.ExternalVolumeStatus) (resultVolumes []*ateapi.ExternalVolumeStatus, err error) { +func createActorVolumes(ctx context.Context, registry VolumePluginRegistry, classes externalVolumeClassGetter, actorUID string, template *ateapi.ActorTemplate, volumesToCreate []*ateapi.ExternalVolumeStatus) (resultVolumes []*ateapi.ExternalVolumeStatus, err error) { resultVolumes = make([]*ateapi.ExternalVolumeStatus, 0, len(volumesToCreate)) var currentIdx int @@ -156,18 +141,18 @@ func createActorVolumes(ctx context.Context, registry VolumePluginRegistry, clas actVolID := actorVolumeID(actorUID, volName) - class, err := resolveVolumeClass(ctx, classes, scLister, specVol.GetExternal().GetTemplate()) + class, err := resolveVolumeClass(ctx, classes, specVol.GetExternal().GetTemplate()) if err != nil { return resultVolumes, err } if class.driver != vol.GetVolumeType() { - return resultVolumes, apierror.FailedPrecondition("volume %q has mismatched type %q (expected %q from %s)", volName, vol.GetVolumeType(), class.driver, class.label) + return resultVolumes, apierror.FailedPrecondition("volume %q has mismatched type %q (expected %q from ExternalVolumeClass %q)", volName, vol.GetVolumeType(), class.driver, class.name) } plugin, err := registry.GetPlugin(ctx, vol.GetVolumeType()) if err != nil { - return resultVolumes, apierror.FailedPrecondition("failed to get volume plugin for driver %q (%s): %v", class.driver, class.label, err) + return resultVolumes, apierror.FailedPrecondition("failed to get volume plugin for driver %q (ExternalVolumeClass %q): %v", class.driver, class.name, err) } resp, volErr := plugin.CreateVolume(ctx, volume.CreateVolumeRequest{ diff --git a/cmd/ateapi/internal/controlapi/volumes_test.go b/cmd/ateapi/internal/controlapi/volumes_test.go index 0fc1e4e4e4..8af31dc23d 100644 --- a/cmd/ateapi/internal/controlapi/volumes_test.go +++ b/cmd/ateapi/internal/controlapi/volumes_test.go @@ -29,35 +29,8 @@ import ( "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/volume" - storagev1 "k8s.io/api/storage/v1" - k8serrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - k8slabels "k8s.io/apimachinery/pkg/labels" - storagev1listers "k8s.io/client-go/listers/storage/v1" ) -type fakeStorageClassLister struct { - storageClasses map[string]*storagev1.StorageClass - getErr error -} - -func (f *fakeStorageClassLister) List(selector k8slabels.Selector) (ret []*storagev1.StorageClass, err error) { - return nil, nil -} - -func (f *fakeStorageClassLister) Get(name string) (*storagev1.StorageClass, error) { - if f.getErr != nil { - return nil, f.getErr - } - sc, ok := f.storageClasses[name] - if !ok { - return nil, k8serrors.NewNotFound(storagev1.Resource("storageclass"), name) - } - return sc, nil -} - -var _ storagev1listers.StorageClassLister = (*fakeStorageClassLister)(nil) - // fakeExternalVolumeClassGetter serves classes from a map and reports a // missing name the way ServiceImpl does. type fakeExternalVolumeClassGetter struct { @@ -76,70 +49,13 @@ func (f *fakeExternalVolumeClassGetter) GetExternalVolumeClass(_ context.Context return class, nil } -func TestActorVolumesStorageClassErrors(t *testing.T) { - ctx := context.Background() - tmpl := &ateapi.ActorTemplate{ - Volumes: []*ateapi.Volume{{ - Name: "data-vol", - External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - StorageClassName: "standard", - }}, - }}, - } - volumes := []*ateapi.ExternalVolumeStatus{{ - Name: "data-vol", - VolumeType: "mock-standard", - }} - - for _, tt := range []struct { - name string - getErr error - wantCode codes.Code - }{ - { - name: "missing StorageClass", - wantCode: codes.FailedPrecondition, - }, - { - name: "StorageClass lookup fails", - getErr: errors.New("storage class cache unavailable"), - wantCode: codes.Internal, - }, - } { - t.Run(tt.name, func(t *testing.T) { - lister := &fakeStorageClassLister{getErr: tt.getErr} - t.Run("initial", func(t *testing.T) { - _, err := initialExternalVolumes(ctx, nil, lister, tmpl) - if got := apierror.Code(err); got != tt.wantCode { - t.Fatalf("initialExternalVolumes() code = %v, want %v; error = %v", got, tt.wantCode, err) - } - if !strings.Contains(err.Error(), `StorageClass "standard"`) { - t.Errorf("initialExternalVolumes() error does not name the StorageClass: %v", err) - } - }) - t.Run("create", func(t *testing.T) { - res, err := createActorVolumes(ctx, &mockPluginRegistry{}, nil, lister, "actor-uid-123", tmpl, volumes) - if got := apierror.Code(err); got != tt.wantCode { - t.Fatalf("createActorVolumes() code = %v, want %v; error = %v", got, tt.wantCode, err) - } - if !strings.Contains(err.Error(), `StorageClass "standard"`) { - t.Errorf("createActorVolumes() error does not name the StorageClass: %v", err) - } - if diff := cmp.Diff(volumes, res, protocmp.Transform()); diff != "" { - t.Errorf("createActorVolumes() did not preserve pending volumes (-want +got):\n%s", diff) - } - }) - }) - } -} - func TestInitialActorVolumes(t *testing.T) { tmpl := &ateapi.ActorTemplate{ Volumes: []*ateapi.Volume{ { Name: "data-vol-1", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - StorageClassName: "standard", + ExternalVolumeClass: &ateapi.ObjectRef{Name: "standard"}, }}, }, { @@ -152,7 +68,7 @@ func TestInitialActorVolumes(t *testing.T) { { Name: "data-vol-2", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - StorageClassName: "fast", + ExternalVolumeClass: &ateapi.ObjectRef{Name: "fast"}, }}, }, }, @@ -170,20 +86,18 @@ func TestInitialActorVolumes(t *testing.T) { }, } - scLister := &fakeStorageClassLister{ - storageClasses: map[string]*storagev1.StorageClass{ + classes := &fakeExternalVolumeClassGetter{ + classes: map[string]*ateapi.ExternalVolumeClass{ "standard": { - ObjectMeta: metav1.ObjectMeta{Name: "standard"}, - Provisioner: "mock-standard", + DriverName: "mock-standard", }, "fast": { - ObjectMeta: metav1.ObjectMeta{Name: "fast"}, - Provisioner: "mock-fast", + DriverName: "mock-fast", MountOptions: []string{"noatime"}, }, }, } - initVols, err := initialExternalVolumes(context.Background(), nil, scLister, tmpl) + initVols, err := initialExternalVolumes(context.Background(), classes, tmpl) if err != nil { t.Fatalf("initialExternalVolumes failed: %v", err) } @@ -200,7 +114,7 @@ func TestCreateActorVolumes(t *testing.T) { { Name: "data-vol", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - StorageClassName: "standard", + ExternalVolumeClass: &ateapi.ObjectRef{Name: "standard"}, }}, }, }, @@ -211,38 +125,38 @@ func TestCreateActorVolumes(t *testing.T) { { Name: "vol1", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - StorageClassName: "standard", + ExternalVolumeClass: &ateapi.ObjectRef{Name: "standard"}, }}, }, { Name: "vol2", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - StorageClassName: "standard", + ExternalVolumeClass: &ateapi.ObjectRef{Name: "standard"}, }}, }, { Name: "vol3", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ - StorageClassName: "standard", + ExternalVolumeClass: &ateapi.ObjectRef{Name: "standard"}, }}, }, }, } tests := []struct { - name string - tmpl *ateapi.ActorTemplate - inputVolumes []*ateapi.ExternalVolumeStatus - storageClasses map[string]*storagev1.StorageClass - wantErr bool - wantRes []*ateapi.ExternalVolumeStatus + name string + tmpl *ateapi.ActorTemplate + inputVolumes []*ateapi.ExternalVolumeStatus + classes map[string]*ateapi.ExternalVolumeClass + wantErr bool + wantRes []*ateapi.ExternalVolumeStatus }{ { name: "partial failure returns error and preserves succeeded, failed, and remaining volumes", tmpl: multiVolTmpl, inputVolumes: []*ateapi.ExternalVolumeStatus{ {Name: "vol1", VolumeType: "mock-standard"}, - // Its type differs from its StorageClass's provisioner, so creating it fails. + // Its type differs from its ExternalVolumeClass's driver, so creating it fails. {Name: "vol2", VolumeType: "mock-fast"}, {Name: "vol3", VolumeType: "mock-standard"}, }, @@ -286,7 +200,7 @@ func TestCreateActorVolumes(t *testing.T) { }, }, { - name: "storage class parameters and mount options are propagated", + name: "class parameters and mount options are propagated", tmpl: standardTmpl, inputVolumes: []*ateapi.ExternalVolumeStatus{ { @@ -294,10 +208,9 @@ func TestCreateActorVolumes(t *testing.T) { VolumeType: "mock-standard", }, }, - storageClasses: map[string]*storagev1.StorageClass{ + classes: map[string]*ateapi.ExternalVolumeClass{ "standard": { - ObjectMeta: metav1.ObjectMeta{Name: "standard"}, - Provisioner: "mock-standard", + DriverName: "mock-standard", Parameters: map[string]string{ "type": "pd-ssd", "csi.storage.k8s.io/fstype": "ext4", @@ -330,21 +243,15 @@ func TestCreateActorVolumes(t *testing.T) { "mock-fast": plugin, }, } - scs := tt.storageClasses - if scs == nil { - scs = map[string]*storagev1.StorageClass{ - "standard": { - ObjectMeta: metav1.ObjectMeta{Name: "standard"}, - Provisioner: "mock-standard", - }, - "fast": { - ObjectMeta: metav1.ObjectMeta{Name: "fast"}, - Provisioner: "mock-fast", - }, + cls := tt.classes + if cls == nil { + cls = map[string]*ateapi.ExternalVolumeClass{ + "standard": {DriverName: "mock-standard"}, + "fast": {DriverName: "mock-fast"}, } } - scLister := &fakeStorageClassLister{storageClasses: scs} - res, err := createActorVolumes(ctx, registry, nil, scLister, "actor-uid-123", tt.tmpl, tt.inputVolumes) + getter := &fakeExternalVolumeClassGetter{classes: cls} + res, err := createActorVolumes(ctx, registry, getter, "actor-uid-123", tt.tmpl, tt.inputVolumes) if (err != nil) != tt.wantErr { t.Errorf("createActorVolumes() error = %v, wantErr %v", err, tt.wantErr) } @@ -355,8 +262,10 @@ func TestCreateActorVolumes(t *testing.T) { } } -func TestResolveExternalVolumeClass(t *testing.T) { - ref := &ateapi.ObjectRef{Name: "gold"} +func TestResolveVolumeClass(t *testing.T) { + tmpl := &ateapi.ExternalVolumeTemplate{ + ExternalVolumeClass: &ateapi.ObjectRef{Name: "gold"}, + } for _, tt := range []struct { name string getter *fakeExternalVolumeClassGetter @@ -387,24 +296,27 @@ func TestResolveExternalVolumeClass(t *testing.T) { wantCode: codes.Internal, }} { t.Run(tt.name, func(t *testing.T) { - driver, params, mountOptions, err := resolveExternalVolumeClass(context.Background(), tt.getter, ref) - if got := apierror.Code(err); got != tt.wantCode { - t.Fatalf("resolveExternalVolumeClass() code = %v, want %v; error = %v", got, tt.wantCode, err) + got, err := resolveVolumeClass(context.Background(), tt.getter, tmpl) + if code := apierror.Code(err); code != tt.wantCode { + t.Fatalf("resolveVolumeClass() code = %v, want %v; error = %v", code, tt.wantCode, err) } if err != nil { if !strings.Contains(err.Error(), `ExternalVolumeClass "gold"`) { - t.Errorf("resolveExternalVolumeClass() error does not name the class: %v", err) + t.Errorf("resolveVolumeClass() error does not name the class: %v", err) } return } - if driver != tt.wantDriver { - t.Errorf("resolveExternalVolumeClass() driver = %q, want %q", driver, tt.wantDriver) + if got.name != "gold" { + t.Errorf("resolveVolumeClass() name = %q, want %q", got.name, "gold") + } + if got.driver != tt.wantDriver { + t.Errorf("resolveVolumeClass() driver = %q, want %q", got.driver, tt.wantDriver) } - if diff := cmp.Diff(tt.wantParams, params); diff != "" { - t.Errorf("resolveExternalVolumeClass() params mismatch (-want +got):\n%s", diff) + if diff := cmp.Diff(tt.wantParams, got.params); diff != "" { + t.Errorf("resolveVolumeClass() params mismatch (-want +got):\n%s", diff) } - if diff := cmp.Diff(tt.wantMountOptions, mountOptions); diff != "" { - t.Errorf("resolveExternalVolumeClass() mountOptions mismatch (-want +got):\n%s", diff) + if diff := cmp.Diff(tt.wantMountOptions, got.mountOptions); diff != "" { + t.Errorf("resolveVolumeClass() mountOptions mismatch (-want +got):\n%s", diff) } }) } @@ -433,7 +345,7 @@ func TestActorVolumesFromExternalVolumeClass(t *testing.T) { }} t.Run("initial volume takes the class driver and mount options", func(t *testing.T) { - got, err := initialExternalVolumes(ctx, classes, nil, tmpl) + got, err := initialExternalVolumes(ctx, classes, tmpl) if err != nil { t.Fatalf("initialExternalVolumes() failed: %v", err) } @@ -449,7 +361,7 @@ func TestActorVolumesFromExternalVolumeClass(t *testing.T) { t.Run("create passes the class parameters and mount options", func(t *testing.T) { input := []*ateapi.ExternalVolumeStatus{{Name: "data-vol", VolumeType: "mock-standard"}} - got, err := createActorVolumes(ctx, registry, classes, nil, "actor-uid-123", tmpl, input) + got, err := createActorVolumes(ctx, registry, classes, "actor-uid-123", tmpl, input) if err != nil { t.Fatalf("createActorVolumes() failed: %v", err) } @@ -467,7 +379,7 @@ func TestActorVolumesFromExternalVolumeClass(t *testing.T) { t.Run("create rejects a volume whose type differs from the class driver", func(t *testing.T) { input := []*ateapi.ExternalVolumeStatus{{Name: "data-vol", VolumeType: "mock-fast"}} - got, err := createActorVolumes(ctx, registry, classes, nil, "actor-uid-123", tmpl, input) + got, err := createActorVolumes(ctx, registry, classes, "actor-uid-123", tmpl, input) if code := apierror.Code(err); code != codes.FailedPrecondition { t.Fatalf("createActorVolumes() code = %v, want %v; error = %v", code, codes.FailedPrecondition, err) } @@ -481,11 +393,11 @@ func TestActorVolumesFromExternalVolumeClass(t *testing.T) { t.Run("missing class is a failed precondition", func(t *testing.T) { missing := &fakeExternalVolumeClassGetter{} - if _, err := initialExternalVolumes(ctx, missing, nil, tmpl); apierror.Code(err) != codes.FailedPrecondition { + if _, err := initialExternalVolumes(ctx, missing, tmpl); apierror.Code(err) != codes.FailedPrecondition { t.Errorf("initialExternalVolumes() error = %v, want FailedPrecondition", err) } input := []*ateapi.ExternalVolumeStatus{{Name: "data-vol", VolumeType: "mock-standard"}} - got, err := createActorVolumes(ctx, registry, missing, nil, "actor-uid-123", tmpl, input) + got, err := createActorVolumes(ctx, registry, missing, "actor-uid-123", tmpl, input) if code := apierror.Code(err); code != codes.FailedPrecondition { t.Fatalf("createActorVolumes() code = %v, want %v; error = %v", code, codes.FailedPrecondition, err) } @@ -499,10 +411,36 @@ func TestActorVolumesFromExternalVolumeClass(t *testing.T) { Name: "data-vol", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: 1 << 30}}, }}} - if _, err := initialExternalVolumes(ctx, classes, nil, noClass); apierror.Code(err) != codes.FailedPrecondition { + if _, err := initialExternalVolumes(ctx, classes, noClass); apierror.Code(err) != codes.FailedPrecondition { t.Errorf("initialExternalVolumes() error = %v, want FailedPrecondition", err) } }) + + t.Run("stored legacy template with storage_class_name is a failed precondition", func(t *testing.T) { + legacy := &ateapi.ActorTemplate{Volumes: []*ateapi.Volume{{ + Name: "data-vol", + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{StorageClassName: "legacy-sc", CapacityBytes: 1 << 30}}, //nolint:staticcheck // SA1019: stored 1.0 preview templates may still carry storage_class_name + }}} + _, err := initialExternalVolumes(ctx, classes, legacy) + if code := apierror.Code(err); code != codes.FailedPrecondition { + t.Fatalf("initialExternalVolumes() code = %v, want %v; error = %v", code, codes.FailedPrecondition, err) + } + if !strings.Contains(err.Error(), `"legacy-sc"`) || !strings.Contains(err.Error(), "external_volume_class") { + t.Errorf("initialExternalVolumes() error = %v, want mention of legacy-sc and external_volume_class", err) + } + + input := []*ateapi.ExternalVolumeStatus{{Name: "data-vol", VolumeType: "mock-standard"}} + got, err := createActorVolumes(ctx, registry, classes, "actor-uid-123", legacy, input) + if code := apierror.Code(err); code != codes.FailedPrecondition { + t.Fatalf("createActorVolumes() code = %v, want %v; error = %v", code, codes.FailedPrecondition, err) + } + if !strings.Contains(err.Error(), `"legacy-sc"`) || !strings.Contains(err.Error(), "external_volume_class") { + t.Errorf("createActorVolumes() error = %v, want mention of legacy-sc and external_volume_class", err) + } + if diff := cmp.Diff(input, got, protocmp.Transform()); diff != "" { + t.Errorf("createActorVolumes() did not preserve pending volumes (-want +got):\n%s", diff) + } + }) } // emptyIDVolumePlugin provisions volumes without returning an ID. @@ -518,18 +456,18 @@ func TestCreateActorVolumesRejectsEmptyPluginID(t *testing.T) { tmpl := &ateapi.ActorTemplate{ Volumes: []*ateapi.Volume{{ Name: "data-vol", - External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{StorageClassName: "standard"}}, + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ExternalVolumeClass: &ateapi.ObjectRef{Name: "standard"}}}, }}, } registry := &mockPluginRegistry{ plugins: map[string]volume.VolumePluginControlPlane{"mock-standard": emptyIDVolumePlugin{}}, } - scLister := &fakeStorageClassLister{storageClasses: map[string]*storagev1.StorageClass{ - "standard": {ObjectMeta: metav1.ObjectMeta{Name: "standard"}, Provisioner: "mock-standard"}, + classes := &fakeExternalVolumeClassGetter{classes: map[string]*ateapi.ExternalVolumeClass{ + "standard": {DriverName: "mock-standard"}, }} input := []*ateapi.ExternalVolumeStatus{{Name: "data-vol", VolumeType: "mock-standard"}} - res, err := createActorVolumes(context.Background(), registry, nil, scLister, "actor-uid-123", tmpl, input) + res, err := createActorVolumes(context.Background(), registry, classes, "actor-uid-123", tmpl, input) if got := apierror.Code(err); got != codes.Internal { t.Fatalf("createActorVolumes() code = %v, want %v; error = %v", got, codes.Internal, err) } diff --git a/cmd/ateapi/internal/controlapi/worker_test.go b/cmd/ateapi/internal/controlapi/worker_test.go index 6f22b94bd2..8408bbfeec 100644 --- a/cmd/ateapi/internal/controlapi/worker_test.go +++ b/cmd/ateapi/internal/controlapi/worker_test.go @@ -72,7 +72,7 @@ func newWorkerAPIService(t *testing.T) (*RPCService, store.Interface) { t.Helper() persistence, cleanup := storetest.SetupTestStore(t) t.Cleanup(cleanup) - impl := newServiceImpl(persistence, nil) + impl := newServiceImpl(persistence) return &RPCService{impl: impl, workerWorkflow: NewWorkerWorkflow(persistence, newNodeAteletDialer(t, &capturingTerminator{}))}, persistence } @@ -783,7 +783,7 @@ func TestServiceImplUpdateWorker_ImmutableFields(t *testing.T) { ctx := context.Background() persistence, cleanup := storetest.SetupTestStore(t) defer cleanup() - impl := newServiceImpl(persistence, nil) + impl := newServiceImpl(persistence) // Every case below is rejected, so nothing writes and this stays the // current incarnation for all of them. @@ -864,7 +864,7 @@ func TestServiceImplAssignmentWrites_ValidateActor(t *testing.T) { ctx := context.Background() persistence, cleanup := storetest.SetupTestStore(t) defer cleanup() - impl := newServiceImpl(persistence, nil) + impl := newServiceImpl(persistence) seedAPIWorker(t, ctx, persistence, validWorker(apiWorkerName)) actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "actor-1"}, diff --git a/cmd/ateapi/internal/controlapi/workflow.go b/cmd/ateapi/internal/controlapi/workflow.go index 834c481e27..1b6479a41b 100644 --- a/cmd/ateapi/internal/controlapi/workflow.go +++ b/cmd/ateapi/internal/controlapi/workflow.go @@ -36,7 +36,6 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/trace" - storagev1listers "k8s.io/client-go/listers/storage/v1" ) // stepSpan opens the per-step trace span ("step." on the controlapi @@ -110,7 +109,6 @@ type ActorWorkflow struct { workerCache *workercache.Cache scheduler scheduling.Scheduler dialer *AteletDialer - storageClassLister storagev1listers.StorageClassLister instruments *Instruments egressGatewayAddress string pluginRegistry VolumePluginRegistry @@ -127,7 +125,6 @@ func NewActorWorkflow( store actorWorkflowStore, workerCache *workercache.Cache, dialer *AteletDialer, - storageClassLister storagev1listers.StorageClassLister, instruments *Instruments, egressGatewayAddress string, pluginRegistry VolumePluginRegistry, @@ -138,7 +135,6 @@ func NewActorWorkflow( workerCache: workerCache, scheduler: scheduling.New(workerCache), dialer: dialer, - storageClassLister: storageClassLister, instruments: instruments, egressGatewayAddress: egressGatewayAddress, pluginRegistry: pluginRegistry, diff --git a/cmd/ateapi/internal/controlapi/workflow_delete_test.go b/cmd/ateapi/internal/controlapi/workflow_delete_test.go index 9dcfba5258..2ae30b9f59 100644 --- a/cmd/ateapi/internal/controlapi/workflow_delete_test.go +++ b/cmd/ateapi/internal/controlapi/workflow_delete_test.go @@ -455,7 +455,7 @@ func TestDeleteActor_CollectsInFlightSnapshotWithoutTemplate(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) objects := objectstoretest.New() - w := NewActorWorkflow(persistence, nil, nil, nil, nil, "", nil, objectstoreplugintest.ControlClient(objects)) + w := NewActorWorkflow(persistence, nil, nil, nil, "", nil, objectstoreplugintest.ControlClient(objects)) actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ @@ -641,7 +641,7 @@ func TestDeleteActorWorkflow_RetryKeepsAdmission(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) objects := objectstoretest.New() - w := NewActorWorkflow(persistence, nil, nil, nil, nil, "", nil, objectstoreplugintest.ControlClient(objects)) + w := NewActorWorkflow(persistence, nil, nil, nil, "", nil, objectstoreplugintest.ControlClient(objects)) actorRef := resources.ActorRef{Atespace: "team-a", Name: "actor-1"} actor := storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ diff --git a/cmd/ateapi/internal/controlapi/workflow_resume.go b/cmd/ateapi/internal/controlapi/workflow_resume.go index ccd34726bc..03ce65e0a1 100644 --- a/cmd/ateapi/internal/controlapi/workflow_resume.go +++ b/cmd/ateapi/internal/controlapi/workflow_resume.go @@ -206,7 +206,7 @@ func (w *ActorWorkflow) ensureVolumesCreated(ctx context.Context, actorRef resou return nil, apierror.FailedPrecondition("cannot create volumes for Actor %s in state %s", actorRef, st) } - volumes, createErr := createActorVolumes(ctx, w.pluginRegistry, w.store, w.storageClassLister, actor.GetMetadata().GetUid(), actorTemplate, actor.GetStatus().GetExternalVolumes().GetVolumes()) + volumes, createErr := createActorVolumes(ctx, w.pluginRegistry, w.store, actor.GetMetadata().GetUid(), actorTemplate, actor.GetStatus().GetExternalVolumes().GetVolumes()) // createActorVolumes reports the state it got to even when it fails, so both // paths persist the same field. updatePrecondition := store.PreconditionFrom(actor) diff --git a/cmd/ateapi/internal/controlapi/workflow_resume_test.go b/cmd/ateapi/internal/controlapi/workflow_resume_test.go index 1c81112384..611f8f10a8 100644 --- a/cmd/ateapi/internal/controlapi/workflow_resume_test.go +++ b/cmd/ateapi/internal/controlapi/workflow_resume_test.go @@ -49,7 +49,6 @@ import ( "google.golang.org/protobuf/proto" "google.golang.org/protobuf/testing/protocmp" corev1 "k8s.io/api/core/v1" - storagev1 "k8s.io/api/storage/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" ) @@ -2031,8 +2030,8 @@ func TestEnsureVolumesAttached_ReturnsPublishContext(t *testing.T) { worker := &ateapi.Worker{NodeName: "node-1"} tmpl := &ateapi.ActorTemplate{ Volumes: []*ateapi.Volume{ - {Name: "mounted", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{StorageClassName: "sc"}}}, - {Name: "unmounted", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{StorageClassName: "sc"}}}, + {Name: "mounted", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ExternalVolumeClass: &ateapi.ObjectRef{Name: "sc"}}}}, + {Name: "unmounted", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ExternalVolumeClass: &ateapi.ObjectRef{Name: "sc"}}}}, }, Containers: []*ateapi.Container{ {Name: "main", Image: "img", VolumeMounts: []*ateapi.VolumeMount{{Name: "mounted", MountPath: "/data"}}}, @@ -2077,7 +2076,7 @@ func TestEnsureVolumesCreated(t *testing.T) { tmpl := &ateapi.ActorTemplate{ Volumes: []*ateapi.Volume{{ Name: "data", - External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{StorageClassName: "sc"}}, + External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ExternalVolumeClass: &ateapi.ObjectRef{Name: "sc"}}}, }}, } tests := []struct { @@ -2093,6 +2092,12 @@ func TestEnsureVolumesCreated(t *testing.T) { t.Run(tt.name, func(t *testing.T) { ctx := context.Background() persistence := newTestPersistence(t) + if _, err := persistence.CreateExternalVolumeClass(ctx, &ateapi.ExternalVolumeClass{ + Metadata: &ateapi.ResourceMetadata{Name: "sc"}, + DriverName: "mock", + }); err != nil { + t.Fatalf("CreateExternalVolumeClass: %v", err) + } actorRef := resources.ActorRef{Atespace: "team-a", Name: "id1"} storetest.MustCreateActor(t, ctx, persistence, &ateapi.Actor{ Metadata: &ateapi.ResourceMetadata{Atespace: "team-a", Name: "id1"}, @@ -2110,9 +2115,6 @@ func TestEnsureVolumesCreated(t *testing.T) { w := &ActorWorkflow{ store: persistence, pluginRegistry: &mockPluginRegistry{plugins: map[string]volume.VolumePluginControlPlane{"mock": plugin}}, - storageClassLister: &fakeStorageClassLister{storageClasses: map[string]*storagev1.StorageClass{ - "sc": {ObjectMeta: metav1.ObjectMeta{Name: "sc"}, Provisioner: "mock"}, - }}, } _, err = w.ensureVolumesCreated(ctx, actorRef, actor, tmpl) @@ -3084,7 +3086,7 @@ func volumeTemplate(declared []string, mounted ...string) *ateapi.ActorTemplate Containers: []*ateapi.Container{{Name: "main", Image: "img"}}, } for _, name := range declared { - tmpl.Volumes = append(tmpl.Volumes, &ateapi.Volume{Name: name, External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{StorageClassName: "sc"}}}) + tmpl.Volumes = append(tmpl.Volumes, &ateapi.Volume{Name: name, External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ExternalVolumeClass: &ateapi.ObjectRef{Name: "sc"}}}}) } for _, name := range mounted { tmpl.Containers[0].VolumeMounts = append(tmpl.Containers[0].VolumeMounts, &ateapi.VolumeMount{Name: name, MountPath: "/" + name}) diff --git a/cmd/ateapi/internal/controlapi/workflow_testutil_test.go b/cmd/ateapi/internal/controlapi/workflow_testutil_test.go index 82c4bf7794..9d51200a2a 100644 --- a/cmd/ateapi/internal/controlapi/workflow_testutil_test.go +++ b/cmd/ateapi/internal/controlapi/workflow_testutil_test.go @@ -58,7 +58,7 @@ func newTestActorWorkflow(t *testing.T, st store.Interface, tmplAtespace, tmplNa }); err != nil && !errors.Is(err, store.ErrAlreadyExists) { t.Fatalf("create test ActorTemplate: %v", err) } - return NewActorWorkflow(st, nil, nil, nil, nil, "", nil, objectstoreplugintest.ControlClient(objectstoretest.New())) + return NewActorWorkflow(st, nil, nil, nil, "", nil, objectstoreplugintest.ControlClient(objectstoretest.New())) } // newFinalizeWorkflow builds an ActorWorkflow over persistence with an diff --git a/cmd/ateapi/main.go b/cmd/ateapi/main.go index 7b08232531..be55fc33b2 100644 --- a/cmd/ateapi/main.go +++ b/cmd/ateapi/main.go @@ -62,7 +62,6 @@ import ( "google.golang.org/grpc/reflection" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/validation/field" - "k8s.io/client-go/informers" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" ) @@ -287,18 +286,14 @@ func main() { csiDriverConfigLister := ateFactory.Ate().V1().CSIDriverConfigs().Lister() ateletPodInformerFactory, ateletPodInformer := controlapi.AteletInformer(clientset, ateletNamespace) - scInformerFactory := informers.NewSharedInformerFactory(clientset, 0) - storageClassLister := scInformerFactory.Storage().V1().StorageClasses().Lister() stopCh := make(chan struct{}) defer close(stopCh) ateletPodInformerFactory.Start(stopCh) ateFactory.Start(stopCh) - scInformerFactory.Start(stopCh) ateletPodInformerFactory.WaitForCacheSync(stopCh) ateFactory.WaitForCacheSync(stopCh) - scInformerFactory.WaitForCacheSync(stopCh) if err := controlapi.RegisterWorkerCount(otel.Meter("ateapi"), workerCache.Workers, workerPoolLister.List); err != nil { serverboot.Fatal(ctx, "Failed to register worker-count metric", err) @@ -347,7 +342,6 @@ func main() { persistence, workerCache, csiDriverConfigLister, - storageClassLister, ateletDialer, instruments, *defaultEgressGatewayAddress, diff --git a/manifests/ate-install/ate-api-server.yaml b/manifests/ate-install/ate-api-server.yaml index 2d55f435d4..60dfe3b36b 100644 --- a/manifests/ate-install/ate-api-server.yaml +++ b/manifests/ate-install/ate-api-server.yaml @@ -30,6 +30,8 @@ rules: - apiGroups: ["ate.dev"] resources: ["workerpools", "csidriverconfigs"] verbs: ["get", "watch", "list"] +# TODO(v1.2): Remove after v1.1; kept so v1.0 ate-api-server pods retain RBAC +# for scInformerFactory.WaitForCacheSync while Deployment/ate-api-server rolls. - apiGroups: ["storage.k8s.io"] resources: ["storageclasses"] verbs: ["get", "watch", "list"] From 6b042553fae8b06ffa6a11d6691f054ab6c39747 Mon Sep 17 00:00:00 2001 From: Vu Le Date: Thu, 12 Nov 2026 00:26:48 +0000 Subject: [PATCH 25/30] forbid storage_class_name and require external_volume_class in ateapi.proto and apivalidation Signed-off-by: Vu Le --- api/ateapi/v1/ateapi.pb.go | 25 ++++++------ api/ateapi/v1/ateapi.proto | 20 ++++------ .../apivalidation/actor_template_test.go | 38 +++++++++---------- .../apivalidation/zz_generated.validation.go | 31 ++++----------- 4 files changed, 44 insertions(+), 70 deletions(-) diff --git a/api/ateapi/v1/ateapi.pb.go b/api/ateapi/v1/ateapi.pb.go index 4cec1354b6..36031253fe 100644 --- a/api/ateapi/v1/ateapi.pb.go +++ b/api/ateapi/v1/ateapi.pb.go @@ -1117,9 +1117,9 @@ type ExternalVolumeStatus struct { // +k8s:update=NoUnset // +k8s:customValidation # no control characters StorageVolumeId string `protobuf:"bytes,2,opt,name=storage_volume_id,json=storageVolumeId,proto3" json:"storage_volume_id,omitempty"` - // Internal volume plugin name or CSI driver name, from the StorageClass - // provisioner. Must be a DNS subdomain, optionally prefixed with - // "substrate.io/" (per the CSI spec's driver-name syntax). + // Internal volume plugin name or CSI driver name, from the + // ExternalVolumeClass driver_name. Must be a DNS subdomain, optionally + // prefixed with "substrate.io/" (per the CSI spec's driver-name syntax). // // +k8s:required // +k8s:maxLength=253 @@ -4009,20 +4009,16 @@ type ExternalVolumeTemplate struct { // +k8s:required // +k8s:minimum=1 CapacityBytes int64 `protobuf:"varint,1,opt,name=capacity_bytes,json=capacityBytes,proto3" json:"capacity_bytes,omitempty"` - // storage_class_name names the cluster-scoped Kubernetes StorageClass to - // create the volume from. Prefer external_volume_class. + // Deprecated: unsupported; use external_volume_class. // - // Exactly one of storage_class_name and external_volume_class must be set. + // +k8s:beta(since: "0.0")=+k8s:forbidden # TODO: get rid of beta prefix // - // +k8s:optional - // +k8s:unionMember - // +k8s:format=k8s-long-name + // Deprecated: Marked as deprecated in api/ateapi/v1/ateapi.proto. StorageClassName string `protobuf:"bytes,2,opt,name=storage_class_name,json=storageClassName,proto3" json:"storage_class_name,omitempty"` // external_volume_class names the ExternalVolumeClass to create the volume // from. atespace must be empty. // - // +k8s:optional - // +k8s:unionMember + // +k8s:required // +k8s:beta(since: "0.0")=+k8s:subfield(atespace)=+k8s:forbidden # TODO: get rid of beta prefix ExternalVolumeClass *ObjectRef `protobuf:"bytes,3,opt,name=external_volume_class,json=externalVolumeClass,proto3" json:"external_volume_class,omitempty"` unknownFields protoimpl.UnknownFields @@ -4066,6 +4062,7 @@ func (x *ExternalVolumeTemplate) GetCapacityBytes() int64 { return 0 } +// Deprecated: Marked as deprecated in api/ateapi/v1/ateapi.proto. func (x *ExternalVolumeTemplate) GetStorageClassName() string { if x != nil { return x.StorageClassName @@ -10588,10 +10585,10 @@ const file_api_ateapi_v1_ateapi_proto_rawDesc = "" + "\btemplate\x18\x01 \x01(\v2+.substrate.ateapi.v1.ExternalVolumeTemplateR\btemplate\"1\n" + "\x11ImageVolumeSource\x12\x1c\n" + "\treference\x18\x01 \x01(\tR\treference\"\x18\n" + - "\x16DurableDirVolumeSource\"\xc1\x01\n" + + "\x16DurableDirVolumeSource\"\xc5\x01\n" + "\x16ExternalVolumeTemplate\x12%\n" + - "\x0ecapacity_bytes\x18\x01 \x01(\x03R\rcapacityBytes\x12,\n" + - "\x12storage_class_name\x18\x02 \x01(\tR\x10storageClassName\x12R\n" + + "\x0ecapacity_bytes\x18\x01 \x01(\x03R\rcapacityBytes\x120\n" + + "\x12storage_class_name\x18\x02 \x01(\tB\x02\x18\x01R\x10storageClassName\x12R\n" + "\x15external_volume_class\x18\x03 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x13externalVolumeClass\"\xd6\x02\n" + "\x13ExternalVolumeClass\x12A\n" + "\bmetadata\x18\x01 \x01(\v2%.substrate.ateapi.v1.ResourceMetadataR\bmetadata\x12\x1f\n" + diff --git a/api/ateapi/v1/ateapi.proto b/api/ateapi/v1/ateapi.proto index 51511e139b..4b401ebdf4 100644 --- a/api/ateapi/v1/ateapi.proto +++ b/api/ateapi/v1/ateapi.proto @@ -536,9 +536,9 @@ message ExternalVolumeStatus { // +k8s:customValidation # no control characters string storage_volume_id = 2; - // Internal volume plugin name or CSI driver name, from the StorageClass - // provisioner. Must be a DNS subdomain, optionally prefixed with - // "substrate.io/" (per the CSI spec's driver-name syntax). + // Internal volume plugin name or CSI driver name, from the + // ExternalVolumeClass driver_name. Must be a DNS subdomain, optionally + // prefixed with "substrate.io/" (per the CSI spec's driver-name syntax). // // +k8s:required // +k8s:maxLength=253 @@ -1585,21 +1585,15 @@ message ExternalVolumeTemplate { // +k8s:minimum=1 int64 capacity_bytes = 1; - // storage_class_name names the cluster-scoped Kubernetes StorageClass to - // create the volume from. Prefer external_volume_class. + // Deprecated: unsupported; use external_volume_class. // - // Exactly one of storage_class_name and external_volume_class must be set. - // - // +k8s:optional - // +k8s:unionMember - // +k8s:format=k8s-long-name - string storage_class_name = 2; + // +k8s:beta(since: "0.0")=+k8s:forbidden # TODO: get rid of beta prefix + string storage_class_name = 2 [ deprecated = true ]; // external_volume_class names the ExternalVolumeClass to create the volume // from. atespace must be empty. // - // +k8s:optional - // +k8s:unionMember + // +k8s:required // +k8s:beta(since: "0.0")=+k8s:subfield(atespace)=+k8s:forbidden # TODO: get rid of beta prefix ObjectRef external_volume_class = 3; } diff --git a/cmd/ateapi/internal/apivalidation/actor_template_test.go b/cmd/ateapi/internal/apivalidation/actor_template_test.go index 7dc0f80efe..1c0edf57bc 100644 --- a/cmd/ateapi/internal/apivalidation/actor_template_test.go +++ b/cmd/ateapi/internal/apivalidation/actor_template_test.go @@ -256,7 +256,8 @@ func TestValidateCreateActorTemplateRequest(t *testing.T) { func TestValidateCreateActorTemplateRequest_PreviewRestricted(t *testing.T) { setPreviewForTest(t, "ALL") req := &ateapi.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapi.ActorTemplate) { - tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: 10 << 30, StorageClassName: "fast-ssd"}}}} + tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: 10 << 30, ExternalVolumeClass: &ateapi.ObjectRef{Name: "fast-ssd"}}}}} + tmpl.Containers[0].VolumeMounts = []*ateapi.VolumeMount{{Name: "data", MountPath: "/var/data"}} tmpl.SnapshotConfig.StorageLocation = "gs://my-bucket/snapshots" })} @@ -913,21 +914,24 @@ func TestValidateActorTemplate(t *testing.T) { }, { name: "valid external volume template", mutate: func(tmpl *ateapi.ActorTemplate) { - tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: 10 << 30, StorageClassName: "fast-ssd"}}}} + tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: 10 << 30, ExternalVolumeClass: &ateapi.ObjectRef{Name: "fast-ssd"}}}}} + tmpl.Containers[0].VolumeMounts = []*ateapi.VolumeMount{{Name: "data", MountPath: "/var/data"}} }, want: field.ErrorList{field.Forbidden(field.NewPath("volumes").Index(0).Child("external"), "")}, wantWithPreview: map[string]field.ErrorList{"ALL": nil}, }, { name: "external volume template missing capacity", mutate: func(tmpl *ateapi.ActorTemplate) { - tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{StorageClassName: "fast-ssd"}}}} + tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{ExternalVolumeClass: &ateapi.ObjectRef{Name: "fast-ssd"}}}}} + tmpl.Containers[0].VolumeMounts = []*ateapi.VolumeMount{{Name: "data", MountPath: "/var/data"}} }, want: field.ErrorList{field.Forbidden(field.NewPath("volumes").Index(0).Child("external"), "")}, wantWithPreview: map[string]field.ErrorList{"ALL": {field.Required(field.NewPath("volumes").Index(0).Child("external", "template", "capacity_bytes"), "")}}, }, { name: "external volume template negative capacity", mutate: func(tmpl *ateapi.ActorTemplate) { - tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: -1, StorageClassName: "fast-ssd"}}}} + tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: -1, ExternalVolumeClass: &ateapi.ObjectRef{Name: "fast-ssd"}}}}} + tmpl.Containers[0].VolumeMounts = []*ateapi.VolumeMount{{Name: "data", MountPath: "/var/data"}} }, want: field.ErrorList{field.Forbidden(field.NewPath("volumes").Index(0).Child("external"), "")}, wantWithPreview: map[string]field.ErrorList{"ALL": {field.Invalid(field.NewPath("volumes").Index(0).Child("external", "template", "capacity_bytes"), nil, "").WithOrigin("minimum")}}, @@ -938,23 +942,26 @@ func TestValidateActorTemplate(t *testing.T) { tmpl.Containers[0].VolumeMounts = []*ateapi.VolumeMount{{Name: "data", MountPath: "/var/data"}} }, want: field.ErrorList{field.Forbidden(field.NewPath("volumes").Index(0).Child("external"), "")}, - wantWithPreview: map[string]field.ErrorList{"ALL": {field.Invalid(field.NewPath("volumes").Index(0).Child("external", "template"), nil, "one of").WithOrigin("union")}}, + wantWithPreview: map[string]field.ErrorList{"ALL": {field.Required(field.NewPath("volumes").Index(0).Child("external", "template", "external_volume_class"), "")}}, }, { - name: "valid external volume template with external_volume_class", + name: "external volume template with forbidden storage_class_name and external_volume_class", mutate: func(tmpl *ateapi.ActorTemplate) { - tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: 10 << 30, ExternalVolumeClass: &ateapi.ObjectRef{Name: "fast-ssd"}}}}} + tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: 10 << 30, StorageClassName: "fast-ssd", ExternalVolumeClass: &ateapi.ObjectRef{Name: "fast-ssd"}}}}} //nolint:staticcheck // SA1019: testing that deprecated storage_class_name is forbidden tmpl.Containers[0].VolumeMounts = []*ateapi.VolumeMount{{Name: "data", MountPath: "/var/data"}} }, want: field.ErrorList{field.Forbidden(field.NewPath("volumes").Index(0).Child("external"), "")}, - wantWithPreview: map[string]field.ErrorList{"ALL": nil}, + wantWithPreview: map[string]field.ErrorList{"ALL": {field.Forbidden(field.NewPath("volumes").Index(0).Child("external", "template", "storage_class_name"), "")}}, }, { - name: "external volume template with both storage_class_name and external_volume_class", + name: "external volume template with only forbidden storage_class_name", mutate: func(tmpl *ateapi.ActorTemplate) { - tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: 10 << 30, StorageClassName: "fast-ssd", ExternalVolumeClass: &ateapi.ObjectRef{Name: "fast-ssd"}}}}} + tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: 10 << 30, StorageClassName: "fast-ssd"}}}} //nolint:staticcheck // SA1019: testing that deprecated storage_class_name is forbidden tmpl.Containers[0].VolumeMounts = []*ateapi.VolumeMount{{Name: "data", MountPath: "/var/data"}} }, - want: field.ErrorList{field.Forbidden(field.NewPath("volumes").Index(0).Child("external"), "")}, - wantWithPreview: map[string]field.ErrorList{"ALL": {field.Invalid(field.NewPath("volumes").Index(0).Child("external", "template"), nil, "one of").WithOrigin("union")}}, + want: field.ErrorList{field.Forbidden(field.NewPath("volumes").Index(0).Child("external"), "")}, + wantWithPreview: map[string]field.ErrorList{"ALL": { + field.Forbidden(field.NewPath("volumes").Index(0).Child("external", "template", "storage_class_name"), ""), + field.Required(field.NewPath("volumes").Index(0).Child("external", "template", "external_volume_class"), ""), + }}, }, { name: "external_volume_class with an atespace", mutate: func(tmpl *ateapi.ActorTemplate) { @@ -971,13 +978,6 @@ func TestValidateActorTemplate(t *testing.T) { }, want: field.ErrorList{field.Forbidden(field.NewPath("volumes").Index(0).Child("external"), "")}, wantWithPreview: map[string]field.ErrorList{"ALL": {field.Required(field.NewPath("volumes").Index(0).Child("external", "template", "external_volume_class", "name"), "")}}, - }, { - name: "external volume template invalid storage_class_name", - mutate: func(tmpl *ateapi.ActorTemplate) { - tmpl.Volumes = []*ateapi.Volume{{Name: "data", External: &ateapi.ExternalVolumeSource{Template: &ateapi.ExternalVolumeTemplate{CapacityBytes: 10 << 30, StorageClassName: "Fast SSD"}}}} - }, - want: field.ErrorList{field.Forbidden(field.NewPath("volumes").Index(0).Child("external"), "")}, - wantWithPreview: map[string]field.ErrorList{"ALL": {field.Invalid(field.NewPath("volumes").Index(0).Child("external", "template", "storage_class_name"), nil, "").WithOrigin("format=k8s-long-name")}}, }, { name: "valid resources", mutate: func(tmpl *ateapi.ActorTemplate) { diff --git a/cmd/ateapi/internal/apivalidation/zz_generated.validation.go b/cmd/ateapi/internal/apivalidation/zz_generated.validation.go index a2b68575b5..83e1ca4d21 100644 --- a/cmd/ateapi/internal/apivalidation/zz_generated.validation.go +++ b/cmd/ateapi/internal/apivalidation/zz_generated.validation.go @@ -4475,31 +4475,12 @@ func Validate_ExternalVolumeStatus( return errs } -var unionMembershipFor_go_ate_dev_substrate_api_ateapi_v1_ExternalVolumeTemplate_ = validate.NewUnionMembership(validate.NewUnionMember("storage_class_name"), validate.NewUnionMember("external_volume_class")) - // Validate_ExternalVolumeTemplate validates an instance of ExternalVolumeTemplate according // to declarative validation rules in the API schema. func Validate_ExternalVolumeTemplate( ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *v1.ExternalVolumeTemplate) (errs field.ErrorList) { - if e := validate.Union(ctx, op, fldPath, obj, oldObj, unionMembershipFor_go_ate_dev_substrate_api_ateapi_v1_ExternalVolumeTemplate_, - func(obj *v1.ExternalVolumeTemplate) bool { - if obj == nil { - return false - } - var z string - return obj.StorageClassName != z - }, - func(obj *v1.ExternalVolumeTemplate) bool { - if obj == nil { - return false - } - return obj.ExternalVolumeClass != nil - }); len(e) != 0 { - errs = append(errs, e...) - } - { // field v1.ExternalVolumeTemplate.CapacityBytes fn := func( fldPath *field.Path, @@ -4545,15 +4526,16 @@ func Validate_ExternalVolumeTemplate( } // call field-attached validations earlyReturn := false - if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + if e := validate.ForbiddenValue(ctx, op, fldPath, obj, oldObj).MarkBeta().MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj).MarkBeta().MarkShortCircuit(); len(e) != 0 { 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, @@ -4576,7 +4558,8 @@ func Validate_ExternalVolumeTemplate( } // call field-attached validations earlyReturn := false - if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + if e := validate.RequiredPointer(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) earlyReturn = true } if earlyReturn { From b99e16816a1eff7d94b21f35bf4325456bee8c2a Mon Sep 17 00:00:00 2001 From: Vu Le Date: Thu, 12 Nov 2026 21:27:54 +0000 Subject: [PATCH 26/30] authz: add allowed_atespace relation and atespace member helper for external volume classes Signed-off-by: Vu Le --- cmd/ateapi/internal/authz/authz_util.go | 36 ++++++++++++++- cmd/ateapi/internal/authz/authz_util_test.go | 46 +++++++++++++++++++ cmd/ateapi/internal/authz/model.fga | 1 + cmd/ateapi/internal/authz/model_test.fga.yaml | 16 ++++++- 4 files changed, 96 insertions(+), 3 deletions(-) diff --git a/cmd/ateapi/internal/authz/authz_util.go b/cmd/ateapi/internal/authz/authz_util.go index 93f6e62088..f5d741114f 100644 --- a/cmd/ateapi/internal/authz/authz_util.go +++ b/cmd/ateapi/internal/authz/authz_util.go @@ -31,6 +31,7 @@ import ( "github.com/spiffe/go-spiffe/v2/spiffeid" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/wrapperspb" + "k8s.io/apimachinery/pkg/api/validate/content" ) const ( @@ -40,10 +41,15 @@ const ( // GlobalRootObject is the singleton global scope object identifier in OpenFGA. GlobalRootObject = "global:root" + atespaceObjectPrefix = "atespace:" + externalVolumeClassObjectPrefix = "external_volume_class:" + RoleOwner = "owner" RoleEditor = "editor" RoleViewer = "viewer" + RoleAllowedAtespace = "allowed_atespace" + RoleController = "controller" RoleEgressGateway = "egress_gateway" RoleIngressRouter = "ingress_router" @@ -122,7 +128,7 @@ var objectIDReplacer = strings.NewReplacer( // AtespaceObject formats an atespace name as an OpenFGA object string. func AtespaceObject(name string) string { - return "atespace:" + objectIDReplacer.Replace(name) + return atespaceObjectPrefix + objectIDReplacer.Replace(name) } // WorkerObject formats a worker name as an OpenFGA object string. Workers are @@ -134,7 +140,7 @@ func WorkerObject(name string) string { // ExternalVolumeClassObject formats an external volume class name as an // OpenFGA object string. External volume classes are global-scoped. func ExternalVolumeClassObject(name string) string { - return "external_volume_class:" + objectIDReplacer.Replace(name) + return externalVolumeClassObjectPrefix + objectIDReplacer.Replace(name) } // ActorObject formats an actor as an OpenFGA object string. @@ -183,6 +189,32 @@ func FormatMember(member string) (string, error) { return formatUser(id), nil } +// validateAtespaceName validates a bare atespace resource name and returns its +// OpenFGA object identifier. +func validateAtespaceName(name string) (string, error) { + if strings.TrimSpace(name) == "" { + return "", fmt.Errorf("atespace name %q must not be empty", name) + } + if errs := content.IsDNS1123Label(name); len(errs) > 0 { + return "", fmt.Errorf("invalid atespace name %q: %s", name, strings.Join(errs, "; ")) + } + return AtespaceObject(name), nil +} + +// FormatAtespaceMember validates an atespace policy member string +// ("atespace:", where is a valid Substrate resource name) and +// returns its OpenFGA object identifier. +func FormatAtespaceMember(member string) (string, error) { + name, ok := strings.CutPrefix(member, atespaceObjectPrefix) + if !ok || strings.TrimSpace(name) == "" { + return "", fmt.Errorf("member %q must have non-empty \"atespace:\" format", member) + } + if name == "*" { + return "", fmt.Errorf("wildcard member %q is not allowed", member) + } + return validateAtespaceName(name) +} + //go:embed model.fga var modelDSL string diff --git a/cmd/ateapi/internal/authz/authz_util_test.go b/cmd/ateapi/internal/authz/authz_util_test.go index 4c66881fc8..812658da59 100644 --- a/cmd/ateapi/internal/authz/authz_util_test.go +++ b/cmd/ateapi/internal/authz/authz_util_test.go @@ -71,6 +71,52 @@ func TestFormatMember(t *testing.T) { } } +func TestFormatAtespaceMember(t *testing.T) { + maxLabel := strings.Repeat("a", 63) + tests := []struct { + name string + member string + want string + wantErr bool + }{ + {name: "plain", member: "atespace:space-1", want: "atespace:space-1"}, + {name: "single character", member: "atespace:a", want: "atespace:a"}, + {name: "max DNS-1123 label length", member: "atespace:" + maxLabel, want: "atespace:" + maxLabel}, + {name: "missing prefix", member: "space-1", wantErr: true}, + {name: "user prefix rejected", member: "user:alice@example.com", wantErr: true}, + {name: "empty name", member: "atespace:", wantErr: true}, + {name: "whitespace name", member: "atespace: ", wantErr: true}, + {name: "wildcard", member: "atespace:*", wantErr: true}, + {name: "userset relation rejected", member: "atespace:space-1#editor", wantErr: true}, + {name: "uppercase rejected", member: "atespace:Space-1", wantErr: true}, + {name: "slash rejected", member: "atespace:a/b", wantErr: true}, + {name: "colon rejected", member: "atespace:a:b", wantErr: true}, + {name: "percent rejected", member: "atespace:a%20b", wantErr: true}, + {name: "leading hyphen rejected", member: "atespace:-bad", wantErr: true}, + {name: "trailing hyphen rejected", member: "atespace:bad-", wantErr: true}, + {name: "too long rejected", member: "atespace:" + maxLabel + "a", wantErr: true}, + {name: "newline rejected", member: "atespace:a\nb", wantErr: true}, + {name: "NUL rejected", member: "atespace:a\x00b", wantErr: true}, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + got, err := FormatAtespaceMember(tc.member) + if tc.wantErr { + if err == nil { + t.Fatalf("FormatAtespaceMember(%q) = %q, want error", tc.member, got) + } + return + } + if err != nil { + t.Fatalf("FormatAtespaceMember(%q) failed: %v", tc.member, err) + } + if got != tc.want { + t.Errorf("FormatAtespaceMember(%q) = %q, want %q", tc.member, got, tc.want) + } + }) + } +} + func TestParseBootstrapOwners(t *testing.T) { got, err := parseBootstrapOwners([]string{"alice@example.com", " user:bob ", "alice@example.com", "a:b"}) if err != nil { diff --git a/cmd/ateapi/internal/authz/model.fga b/cmd/ateapi/internal/authz/model.fga index e450b762db..592083fb81 100644 --- a/cmd/ateapi/internal/authz/model.fga +++ b/cmd/ateapi/internal/authz/model.fga @@ -78,6 +78,7 @@ type global type external_volume_class relations define parent_global: [global] + define allowed_atespace: [atespace] define can_get: viewer from parent_global define can_delete: owner from parent_global diff --git a/cmd/ateapi/internal/authz/model_test.fga.yaml b/cmd/ateapi/internal/authz/model_test.fga.yaml index c0806f9e91..09d64262df 100644 --- a/cmd/ateapi/internal/authz/model_test.fga.yaml +++ b/cmd/ateapi/internal/authz/model_test.fga.yaml @@ -94,10 +94,16 @@ tuples: relation: api_server_sidecar object: global:root - # External volume class (nfs-gold linked to global:root) + # External volume classes (linked to global:root; space-1 allowed on nfs-gold only) - user: global:root relation: parent_global object: external_volume_class:nfs-gold + - user: atespace:space-1 + relation: allowed_atespace + object: external_volume_class:nfs-gold + - user: global:root + relation: parent_global + object: external_volume_class:ssd-restricted tests: - name: 1. Global Superadmin & Viewer Propagation @@ -610,3 +616,11 @@ tests: assertions: can_get: false can_delete: false + - user: atespace:space-1 + object: external_volume_class:nfs-gold + assertions: + allowed_atespace: true + - user: atespace:space-1 + object: external_volume_class:ssd-restricted + assertions: + allowed_atespace: false From 60e6413d73d3abb1526ca338d6fb941f81401102 Mon Sep 17 00:00:00 2001 From: Vu Le Date: Thu, 12 Nov 2026 21:28:10 +0000 Subject: [PATCH 27/30] authz: reconcile external volume class atespace grants and remove them when an atespace is deleted Signed-off-by: Vu Le --- cmd/ateapi/internal/authz/authz_test.go | 249 ++++++++++++++++++ cmd/ateapi/internal/authz/policy_manager.go | 74 +++++- .../store/atepg/access_policy_test.go | 73 +++++ cmd/ateapi/internal/store/atepg/atespace.go | 3 + 4 files changed, 393 insertions(+), 6 deletions(-) diff --git a/cmd/ateapi/internal/authz/authz_test.go b/cmd/ateapi/internal/authz/authz_test.go index 6fec93a806..f408eb5d3f 100644 --- a/cmd/ateapi/internal/authz/authz_test.go +++ b/cmd/ateapi/internal/authz/authz_test.go @@ -17,6 +17,7 @@ package authz import ( "context" "errors" + "fmt" "os" "os/exec" "runtime" @@ -33,6 +34,7 @@ import ( "github.com/testcontainers/testcontainers-go/modules/postgres" "google.golang.org/grpc/codes" + "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/store/dockerenv" "go.ate.dev/substrate/internal/apierror" "go.ate.dev/substrate/internal/principal" @@ -566,3 +568,250 @@ func TestAtespacedObjects_NoCollision(t *testing.T) { t.Errorf("ActorObject and ActorTemplateObject collided on %q", o1) } } + +func TestPolicyManager_ExternalVolumeClassAtespaces(t *testing.T) { + pool := startPostgres(t) + ctx := context.Background() + + fgaSrv, err := NewOpenFGAServer(pool) + if err != nil { + t.Fatalf("NewOpenFGAServer failed: %v", err) + } + t.Cleanup(fgaSrv.Close) + + _, pm, err := New(ctx, pool, fgaSrv, nil, testSystemPrincipals()) + if err != nil { + t.Fatalf("authz.New failed: %v", err) + } + + checkAllowedAtespace := func(atespace, class string) bool { + t.Helper() + resp, err := fgaSrv.Check(ctx, &openfgav1.CheckRequest{ + StoreId: pm.storeID, + AuthorizationModelId: pm.modelID, + TupleKey: &openfgav1.CheckRequestTupleKey{ + User: AtespaceObject(atespace), + Relation: RoleAllowedAtespace, + Object: ExternalVolumeClassObject(class), + }, + }) + if err != nil { + t.Fatalf("Check(%s, %s, %s) failed: %v", atespace, RoleAllowedAtespace, class, err) + } + return resp.GetAllowed() + } + + // 1. Nil transaction checks. + if err := pm.ReconcileExternalVolumeClassAtespaces(ctx, nil, "nfs-gold", nil); !errors.Is(err, ErrNilTransaction) { + t.Fatalf("ReconcileExternalVolumeClassAtespaces(nil tx) = %v, want ErrNilTransaction", err) + } + if err := pm.DeleteExternalVolumeClassPolicies(ctx, nil, "nfs-gold"); !errors.Is(err, ErrNilTransaction) { + t.Fatalf("DeleteExternalVolumeClassPolicies(nil tx) = %v, want ErrNilTransaction", err) + } + if err := pm.RemoveAtespaceFromExternalVolumeClasses(ctx, nil, "space-1"); !errors.Is(err, ErrNilTransaction) { + t.Fatalf("RemoveAtespaceFromExternalVolumeClasses(nil tx) = %v, want ErrNilTransaction", err) + } + + // 2. Invalid member, disallowed role, and invalid atespace name checks. + for _, badMember := range []string{"user:alice", "atespace:*", "atespace:Bad", "atespace:space-1#editor"} { + tx, err := pool.Begin(ctx) + if err != nil { + t.Fatalf("pool.Begin failed: %v", err) + } + err = pm.ReconcileExternalVolumeClassAtespaces(ctx, tx, "nfs-gold", []*ateapi.Binding{ + {Role: RoleAllowedAtespace, Members: []string{badMember}}, + }) + _ = tx.Rollback(ctx) + if err == nil { + t.Errorf("ReconcileExternalVolumeClassAtespaces(%q) succeeded, want error", badMember) + } + } + for _, badRole := range []string{RoleOwner, RoleViewer, "parent_global", RelationCanGet, "not-a-relation"} { + tx, err := pool.Begin(ctx) + if err != nil { + t.Fatalf("pool.Begin failed: %v", err) + } + err = pm.ReconcileExternalVolumeClassAtespaces(ctx, tx, "nfs-gold", []*ateapi.Binding{ + {Role: badRole, Members: []string{"atespace:space-1"}}, + }) + _ = tx.Rollback(ctx) + if err == nil { + t.Errorf("ReconcileExternalVolumeClassAtespaces(role=%q) succeeded, want error", badRole) + } + } + for _, badAtespace := range []string{"", "*", "Bad", "space-1#editor"} { + tx, err := pool.Begin(ctx) + if err != nil { + t.Fatalf("pool.Begin failed: %v", err) + } + err = pm.RemoveAtespaceFromExternalVolumeClasses(ctx, tx, badAtespace) + _ = tx.Rollback(ctx) + if err == nil { + t.Errorf("RemoveAtespaceFromExternalVolumeClasses(%q) succeeded, want error", badAtespace) + } + } + + // 3. Reconcile initial grant (with duplicate member deduplication) + diff update + rollback atomicity. + tx, err := pool.Begin(ctx) + if err != nil { + t.Fatalf("pool.Begin failed: %v", err) + } + if err := pm.ReconcileExternalVolumeClassAtespaces(ctx, tx, "nfs-gold", []*ateapi.Binding{ + {Role: RoleAllowedAtespace, Members: []string{"atespace:space-1", "atespace:space-2", "atespace:space-1"}}, + }); err != nil { + _ = tx.Rollback(ctx) + t.Fatalf("ReconcileExternalVolumeClassAtespaces initial grant failed: %v", err) + } + if err := tx.Commit(ctx); err != nil { + t.Fatalf("tx.Commit failed: %v", err) + } + if !checkAllowedAtespace("space-1", "nfs-gold") || !checkAllowedAtespace("space-2", "nfs-gold") { + t.Fatalf("expected space-1 and space-2 allowed on nfs-gold") + } + if checkAllowedAtespace("space-3", "nfs-gold") { + t.Fatalf("expected space-3 denied on nfs-gold") + } + + // Rolled-back reconcile leaves committed tuples unchanged. + txRollback, err := pool.Begin(ctx) + if err != nil { + t.Fatalf("pool.Begin failed: %v", err) + } + if err := pm.ReconcileExternalVolumeClassAtespaces(ctx, txRollback, "nfs-gold", nil); err != nil { + t.Fatalf("ReconcileExternalVolumeClassAtespaces(nil) failed: %v", err) + } + if err := txRollback.Rollback(ctx); err != nil { + t.Fatalf("Rollback failed: %v", err) + } + if !checkAllowedAtespace("space-1", "nfs-gold") || !checkAllowedAtespace("space-2", "nfs-gold") { + t.Fatalf("expected space-1 and space-2 still allowed after rolled-back clear") + } + + // Update nfs-gold from {space-1, space-2} to {space-2, space-3}. + txUpdate, err := pool.Begin(ctx) + if err != nil { + t.Fatalf("pool.Begin failed: %v", err) + } + if err := pm.ReconcileExternalVolumeClassAtespaces(ctx, txUpdate, "nfs-gold", []*ateapi.Binding{ + {Role: RoleAllowedAtespace, Members: []string{"atespace:space-2", "atespace:space-3"}}, + }); err != nil { + _ = txUpdate.Rollback(ctx) + t.Fatalf("ReconcileExternalVolumeClassAtespaces update failed: %v", err) + } + if err := txUpdate.Commit(ctx); err != nil { + t.Fatalf("txUpdate.Commit failed: %v", err) + } + if checkAllowedAtespace("space-1", "nfs-gold") { + t.Errorf("expected space-1 removed from nfs-gold") + } + if !checkAllowedAtespace("space-2", "nfs-gold") || !checkAllowedAtespace("space-3", "nfs-gold") { + t.Errorf("expected space-2 and space-3 allowed on nfs-gold") + } + + // 4. DeleteExternalVolumeClassPolicies clears only the targeted class. + txSSD, err := pool.Begin(ctx) + if err != nil { + t.Fatalf("pool.Begin failed: %v", err) + } + if err := pm.ReconcileExternalVolumeClassAtespaces(ctx, txSSD, "ssd-fast", []*ateapi.Binding{ + {Role: RoleAllowedAtespace, Members: []string{"atespace:space-2"}}, + }); err != nil { + _ = txSSD.Rollback(ctx) + t.Fatalf("ReconcileExternalVolumeClassAtespaces(ssd-fast) failed: %v", err) + } + if err := txSSD.Commit(ctx); err != nil { + t.Fatalf("txSSD.Commit failed: %v", err) + } + + txDelClass, err := pool.Begin(ctx) + if err != nil { + t.Fatalf("pool.Begin failed: %v", err) + } + if err := pm.DeleteExternalVolumeClassPolicies(ctx, txDelClass, "ssd-fast"); err != nil { + _ = txDelClass.Rollback(ctx) + t.Fatalf("DeleteExternalVolumeClassPolicies(ssd-fast) failed: %v", err) + } + if err := txDelClass.Commit(ctx); err != nil { + t.Fatalf("txDelClass.Commit failed: %v", err) + } + if checkAllowedAtespace("space-2", "ssd-fast") { + t.Errorf("expected space-2 removed from ssd-fast after DeleteExternalVolumeClassPolicies") + } + if !checkAllowedAtespace("space-2", "nfs-gold") { + t.Errorf("expected nfs-gold untouched by DeleteExternalVolumeClassPolicies(ssd-fast)") + } + + // 5. Reverse sweep across > maxTuplesPerWrite (105 classes) exercises both + // paginated reads and chunked deletes within one transaction. + const totalClasses = maxTuplesPerWrite + 5 + txSeedMany, err := pool.Begin(ctx) + if err != nil { + t.Fatalf("pool.Begin failed: %v", err) + } + for i := range totalClasses { + className := fmt.Sprintf("class-%03d", i) + members := []string{"atespace:ephemeral"} + if i == 0 { + members = append(members, "atespace:survivor") + } + if err := pm.ReconcileExternalVolumeClassAtespaces(ctx, txSeedMany, className, []*ateapi.Binding{ + {Role: RoleAllowedAtespace, Members: members}, + }); err != nil { + _ = txSeedMany.Rollback(ctx) + t.Fatalf("seeding %s failed: %v", className, err) + } + } + if err := txSeedMany.Commit(ctx); err != nil { + t.Fatalf("txSeedMany.Commit failed: %v", err) + } + + // Rolled-back sweep leaves all seeded tuples intact. + txSweepRollback, err := pool.Begin(ctx) + if err != nil { + t.Fatalf("pool.Begin failed: %v", err) + } + if err := pm.RemoveAtespaceFromExternalVolumeClasses(ctx, txSweepRollback, "ephemeral"); err != nil { + _ = txSweepRollback.Rollback(ctx) + t.Fatalf("RemoveAtespaceFromExternalVolumeClasses(rollback) failed: %v", err) + } + if err := txSweepRollback.Rollback(ctx); err != nil { + t.Fatalf("txSweepRollback.Rollback failed: %v", err) + } + if !checkAllowedAtespace("ephemeral", "class-000") || !checkAllowedAtespace("ephemeral", "class-104") { + t.Fatalf("expected ephemeral still allowed after rolled-back sweep") + } + + txSweep, err := pool.Begin(ctx) + if err != nil { + t.Fatalf("pool.Begin failed: %v", err) + } + if err := pm.RemoveAtespaceFromExternalVolumeClasses(ctx, txSweep, "ephemeral"); err != nil { + _ = txSweep.Rollback(ctx) + t.Fatalf("RemoveAtespaceFromExternalVolumeClasses(ephemeral) failed: %v", err) + } + if err := txSweep.Commit(ctx); err != nil { + t.Fatalf("txSweep.Commit failed: %v", err) + } + for i := range totalClasses { + className := fmt.Sprintf("class-%03d", i) + if checkAllowedAtespace("ephemeral", className) { + t.Fatalf("expected ephemeral removed from %s", className) + } + } + if !checkAllowedAtespace("survivor", "class-000") { + t.Errorf("expected survivor retained on class-000") + } + + // Second sweep is a no-op. + txNoop, err := pool.Begin(ctx) + if err != nil { + t.Fatalf("pool.Begin failed: %v", err) + } + if err := pm.RemoveAtespaceFromExternalVolumeClasses(ctx, txNoop, "ephemeral"); err != nil { + _ = txNoop.Rollback(ctx) + t.Fatalf("second RemoveAtespaceFromExternalVolumeClasses(ephemeral) failed: %v", err) + } + if err := txNoop.Commit(ctx); err != nil { + t.Fatalf("txNoop.Commit failed: %v", err) + } +} diff --git a/cmd/ateapi/internal/authz/policy_manager.go b/cmd/ateapi/internal/authz/policy_manager.go index 762279cf57..795cbc85c7 100644 --- a/cmd/ateapi/internal/authz/policy_manager.go +++ b/cmd/ateapi/internal/authz/policy_manager.go @@ -41,19 +41,71 @@ type PolicyManager struct { // ReconcileGlobalBindings reconciles the OpenFGA role bindings on global:root // within tx. The tuple changes commit or roll back with tx. func (m *PolicyManager) ReconcileGlobalBindings(ctx context.Context, tx pgx.Tx, bindings []*ateapi.Binding) error { - return m.reconcileBindings(ctx, tx, GlobalRootObject, bindings) + return m.reconcileBindings(ctx, tx, GlobalRootObject, bindings, FormatMember) } // ReconcileAtespaceBindings reconciles the OpenFGA role bindings on an atespace // within tx. The tuple changes commit or roll back with tx. func (m *PolicyManager) ReconcileAtespaceBindings(ctx context.Context, tx pgx.Tx, name string, bindings []*ateapi.Binding) error { - return m.reconcileBindings(ctx, tx, AtespaceObject(name), bindings) + return m.reconcileBindings(ctx, tx, AtespaceObject(name), bindings, FormatMember) } // DeleteAtespacePolicies removes all OpenFGA tuples associated with an atespace // within tx. The tuple deletions commit or roll back with tx. func (m *PolicyManager) DeleteAtespacePolicies(ctx context.Context, tx pgx.Tx, name string) error { - return m.reconcileBindings(ctx, tx, AtespaceObject(name), nil) + return m.reconcileBindings(ctx, tx, AtespaceObject(name), nil, FormatMember) +} + +// ReconcileExternalVolumeClassAtespaces reconciles the OpenFGA allowed-atespace +// bindings on an external volume class within tx. The tuple changes commit or +// roll back with tx. +func (m *PolicyManager) ReconcileExternalVolumeClassAtespaces(ctx context.Context, tx pgx.Tx, name string, bindings []*ateapi.Binding) error { + return m.reconcileBindings(ctx, tx, ExternalVolumeClassObject(name), bindings, FormatAtespaceMember) +} + +// DeleteExternalVolumeClassPolicies removes all OpenFGA tuples associated with +// an external volume class within tx. The tuple deletions commit or roll back +// with tx. +func (m *PolicyManager) DeleteExternalVolumeClassPolicies(ctx context.Context, tx pgx.Tx, name string) error { + return m.reconcileBindings(ctx, tx, ExternalVolumeClassObject(name), nil, FormatAtespaceMember) +} + +// RemoveAtespaceFromExternalVolumeClasses deletes all OpenFGA tuples granting +// the named atespace access to any external volume class within tx. +func (m *PolicyManager) RemoveAtespaceFromExternalVolumeClasses(ctx context.Context, tx pgx.Tx, name string) error { + if tx == nil { + return ErrNilTransaction + } + user, err := validateAtespaceName(name) + if err != nil { + return err + } + ctx = ContextWithTx(ctx, tx) + + tuples, err := m.readTuples(ctx, &openfgav1.ReadRequestTupleKey{ + User: user, + Object: externalVolumeClassObjectPrefix, + }) + if err != nil { + return fmt.Errorf("reading external volume class tuples for %q: %w", user, err) + } + if len(tuples) == 0 { + return nil + } + + toDelete := make([]*openfgav1.TupleKeyWithoutCondition, 0, len(tuples)) + for _, tk := range tuples { + toDelete = append(toDelete, &openfgav1.TupleKeyWithoutCondition{ + User: tk.GetUser(), + Relation: tk.GetRelation(), + Object: tk.GetObject(), + }) + } + + if err := m.applyMutationsChunked(ctx, nil, toDelete); err != nil { + return fmt.Errorf("removing %q from external volume class tuples: %w", user, err) + } + return nil } func (m *PolicyManager) applyMutationsChunked(ctx context.Context, toWrite []*openfgav1.TupleKey, toDelete []*openfgav1.TupleKeyWithoutCondition) error { @@ -87,12 +139,16 @@ func (m *PolicyManager) applyMutationsChunked(ctx context.Context, toWrite []*op } func (m *PolicyManager) readObjectTuples(ctx context.Context, obj string) ([]*openfgav1.TupleKey, error) { + return m.readTuples(ctx, &openfgav1.ReadRequestTupleKey{Object: obj}) +} + +func (m *PolicyManager) readTuples(ctx context.Context, filter *openfgav1.ReadRequestTupleKey) ([]*openfgav1.TupleKey, error) { var out []*openfgav1.TupleKey var contToken string for { readResp, err := m.fgaServer.Read(ctx, &openfgav1.ReadRequest{ StoreId: m.storeID, - TupleKey: &openfgav1.ReadRequestTupleKey{Object: obj}, + TupleKey: filter, PageSize: wrapperspb.Int32(maxTuplesPerWrite), ContinuationToken: contToken, }) @@ -115,7 +171,13 @@ func (m *PolicyManager) readObjectTuples(ctx context.Context, obj string) ([]*op // reconcileBindings diffs the existing OpenFGA tuples on obj against // desiredBindings and writes only the net additions and deletions in batches // within tx, leaving unchanged (relation, user) tuples untouched. -func (m *PolicyManager) reconcileBindings(ctx context.Context, tx pgx.Tx, obj string, desiredBindings []*ateapi.Binding) error { +func (m *PolicyManager) reconcileBindings( + ctx context.Context, + tx pgx.Tx, + obj string, + desiredBindings []*ateapi.Binding, + formatMember func(string) (string, error), +) error { if tx == nil { return ErrNilTransaction } @@ -142,7 +204,7 @@ func (m *PolicyManager) reconcileBindings(ctx context.Context, tx pgx.Tx, obj st for _, b := range desiredBindings { role := b.GetRole() for _, rawMember := range b.GetMembers() { - fgaUser, err := FormatMember(rawMember) + fgaUser, err := formatMember(rawMember) if err != nil { return err } diff --git a/cmd/ateapi/internal/store/atepg/access_policy_test.go b/cmd/ateapi/internal/store/atepg/access_policy_test.go index 4461178a30..39169f107d 100644 --- a/cmd/ateapi/internal/store/atepg/access_policy_test.go +++ b/cmd/ateapi/internal/store/atepg/access_policy_test.go @@ -261,3 +261,76 @@ func TestGlobalAccessPolicy_UpdateIsAtomic(t *testing.T) { } }) } + +func externalVolumeClassTuples(t *testing.T, p *Persistence, className string) []string { + t.Helper() + rows, err := p.pool.Query(t.Context(), + `SELECT relation, _user FROM tuple WHERE object_type = 'external_volume_class' AND object_id = $1`, + className) + if err != nil { + t.Fatalf("reading external volume class tuples: %v", err) + } + defer rows.Close() + var out []string + for rows.Next() { + var relation, user string + if err := rows.Scan(&relation, &user); err != nil { + t.Fatalf("scanning tuple: %v", err) + } + out = append(out, relation+" "+user) + } + if err := rows.Err(); err != nil { + t.Fatalf("reading external volume class tuples: %v", err) + } + slices.Sort(out) + return out +} + +func TestDeleteAtespace_SweepsExternalVolumeClassTuples(t *testing.T) { + p := setupPostgresPersistence(t) + ctx := t.Context() + + for _, space := range []string{"team-a", "team-b"} { + if _, err := p.CreateAtespace(ctx, newTestAtespace(space)); err != nil { + t.Fatalf("CreateAtespace(%s) failed: %v", space, err) + } + } + + tx, err := p.pool.Begin(ctx) + if err != nil { + t.Fatalf("pool.Begin failed: %v", err) + } + defer tx.Rollback(ctx) //nolint:errcheck // no-op once committed + if err := p.policyManager.ReconcileExternalVolumeClassAtespaces(ctx, tx, "nfs-gold", []*ateapi.Binding{ + {Role: authz.RoleAllowedAtespace, Members: []string{"atespace:team-a", "atespace:team-b"}}, + }); err != nil { + t.Fatalf("ReconcileExternalVolumeClassAtespaces(nfs-gold) failed: %v", err) + } + if err := p.policyManager.ReconcileExternalVolumeClassAtespaces(ctx, tx, "ssd-fast", []*ateapi.Binding{ + {Role: authz.RoleAllowedAtespace, Members: []string{"atespace:team-a"}}, + }); err != nil { + t.Fatalf("ReconcileExternalVolumeClassAtespaces(ssd-fast) failed: %v", err) + } + if err := tx.Commit(ctx); err != nil { + t.Fatalf("tx.Commit failed: %v", err) + } + + // Precondition mismatch aborts before sweeping tuples. + if _, err := p.DeleteAtespace(ctx, "team-a", store.DeletePreconditions{Version: 99}); !errors.Is(err, store.ErrVersionConflict) { + t.Fatalf("DeleteAtespace wrong version = %v, want ErrVersionConflict", err) + } + if diff := cmp.Diff([]string{"allowed_atespace atespace:team-a", "allowed_atespace atespace:team-b"}, externalVolumeClassTuples(t, p, "nfs-gold")); diff != "" { + t.Fatalf("nfs-gold tuples changed on failed delete (-want +got):\n%s", diff) + } + + // Deleting team-a sweeps its external volume class tuples while preserving team-b's. + if _, err := p.DeleteAtespace(ctx, "team-a", store.DeletePreconditions{}); err != nil { + t.Fatalf("DeleteAtespace(team-a) failed: %v", err) + } + if diff := cmp.Diff([]string{"allowed_atespace atespace:team-b"}, externalVolumeClassTuples(t, p, "nfs-gold")); diff != "" { + t.Errorf("nfs-gold tuples after DeleteAtespace(team-a) (-want +got):\n%s", diff) + } + if got := externalVolumeClassTuples(t, p, "ssd-fast"); len(got) != 0 { + t.Errorf("ssd-fast tuples after DeleteAtespace(team-a) = %v, want empty", got) + } +} diff --git a/cmd/ateapi/internal/store/atepg/atespace.go b/cmd/ateapi/internal/store/atepg/atespace.go index 6d0f163e3b..e958c30609 100644 --- a/cmd/ateapi/internal/store/atepg/atespace.go +++ b/cmd/ateapi/internal/store/atepg/atespace.go @@ -147,6 +147,9 @@ func (p *Persistence) DeleteAtespace(ctx context.Context, name string, precondit if err := p.policyManager.DeleteAtespacePolicies(ctx, tx, name); err != nil { return nil, fmt.Errorf("deleting authorization tuples for atespace %q: %w", name, err) } + if err := p.policyManager.RemoveAtespaceFromExternalVolumeClasses(ctx, tx, name); err != nil { + return nil, fmt.Errorf("removing atespace %q from external volume class policies: %w", name, err) + } if err := tx.Commit(ctx); err != nil { return nil, fmt.Errorf("committing atespace delete %q: %w", name, err) } From 0acc653ebffd1a7313cbb432ce706a5f9c626961 Mon Sep 17 00:00:00 2001 From: Vu Le Date: Fri, 13 Nov 2026 19:16:32 +0000 Subject: [PATCH 28/30] add editor from allowed_atespace on evc can_get and add CRUD policy on evc in model.fga with OpenFGA model tests Signed-off-by: Vu Le --- cmd/ateapi/internal/authz/authz_test.go | 50 ++++++++++++++++++- cmd/ateapi/internal/authz/model.fga | 10 +++- cmd/ateapi/internal/authz/model_test.fga.yaml | 41 +++++++++++++-- 3 files changed, 94 insertions(+), 7 deletions(-) diff --git a/cmd/ateapi/internal/authz/authz_test.go b/cmd/ateapi/internal/authz/authz_test.go index f408eb5d3f..f99c6a5d84 100644 --- a/cmd/ateapi/internal/authz/authz_test.go +++ b/cmd/ateapi/internal/authz/authz_test.go @@ -579,7 +579,7 @@ func TestPolicyManager_ExternalVolumeClassAtespaces(t *testing.T) { } t.Cleanup(fgaSrv.Close) - _, pm, err := New(ctx, pool, fgaSrv, nil, testSystemPrincipals()) + authorizer, pm, err := New(ctx, pool, fgaSrv, []string{"root-owner"}, testSystemPrincipals()) if err != nil { t.Fatalf("authz.New failed: %v", err) } @@ -814,4 +814,52 @@ func TestPolicyManager_ExternalVolumeClassAtespaces(t *testing.T) { if err := txNoop.Commit(ctx); err != nil { t.Fatalf("txNoop.Commit failed: %v", err) } + + // 6. Runtime Authorizer.Check evaluation with contextual parent_global tuples: + // - Bootstrap/global owner manages the class and its access policy. + // - Editor of allowed atespace (space-2 on nfs-gold) can Get the class, but + // cannot Delete it, read/write its access policy, or Get a disallowed class. + // - Viewer of allowed atespace cannot Get the class. + writeTestTuple(t, ctx, pool, pm, "bob", RoleEditor, AtespaceObject("space-2")) + writeTestTuple(t, ctx, pool, pm, "dave", RoleViewer, AtespaceObject("space-2")) + + rootCtx := principal.InjectContext(ctx, principal.PrincipalInfo{ID: "root-owner", Kind: principal.KindJWT}) + bobCtx := principal.InjectContext(ctx, principal.PrincipalInfo{ID: "bob", Kind: principal.KindJWT}) + daveCtx := principal.InjectContext(ctx, principal.PrincipalInfo{ID: "dave", Kind: principal.KindJWT}) + + nfsGoldObj := ExternalVolumeClassObject("nfs-gold") + ssdFastObj := ExternalVolumeClassObject("ssd-fast") + + for _, rel := range []string{ + RelationCanGet, + RelationCanDelete, + RelationCanCreateAccessPolicy, + RelationCanGetAccessPolicy, + RelationCanUpdateAccessPolicy, + RelationCanDeleteAccessPolicy, + } { + if err := authorizer.Check(rootCtx, rel, nfsGoldObj); err != nil { + t.Errorf("expected root-owner allowed %s on nfs-gold, got %v", rel, err) + } + } + if err := authorizer.Check(bobCtx, RelationCanGet, nfsGoldObj); err != nil { + t.Errorf("expected allowed-atespace editor bob allowed can_get on nfs-gold, got %v", err) + } + for _, rel := range []string{ + RelationCanDelete, + RelationCanCreateAccessPolicy, + RelationCanGetAccessPolicy, + RelationCanUpdateAccessPolicy, + RelationCanDeleteAccessPolicy, + } { + if err := authorizer.Check(bobCtx, rel, nfsGoldObj); apierror.Code(err) != codes.PermissionDenied { + t.Errorf("expected bob denied %s on nfs-gold, got %v", rel, err) + } + } + if err := authorizer.Check(bobCtx, RelationCanGet, ssdFastObj); apierror.Code(err) != codes.PermissionDenied { + t.Errorf("expected bob denied can_get on disallowed ssd-fast, got %v", err) + } + if err := authorizer.Check(daveCtx, RelationCanGet, nfsGoldObj); apierror.Code(err) != codes.PermissionDenied { + t.Errorf("expected allowed-atespace viewer dave denied can_get on nfs-gold, got %v", err) + } } diff --git a/cmd/ateapi/internal/authz/model.fga b/cmd/ateapi/internal/authz/model.fga index 592083fb81..500982ba41 100644 --- a/cmd/ateapi/internal/authz/model.fga +++ b/cmd/ateapi/internal/authz/model.fga @@ -74,13 +74,19 @@ type global define can_get_access_policy: viewer define can_update_access_policy: owner -# Global-scoped; inherits its roles from global. +# Global-scoped; inherits its roles from global, and editors of allowed +# atespaces may read the class. type external_volume_class relations define parent_global: [global] define allowed_atespace: [atespace] - define can_get: viewer from parent_global + define can_create_access_policy: owner from parent_global + define can_get_access_policy: viewer from parent_global + define can_update_access_policy: owner from parent_global + define can_delete_access_policy: owner from parent_global + + define can_get: viewer from parent_global or editor from allowed_atespace define can_delete: owner from parent_global type atespace diff --git a/cmd/ateapi/internal/authz/model_test.fga.yaml b/cmd/ateapi/internal/authz/model_test.fga.yaml index 09d64262df..5d0d4617c9 100644 --- a/cmd/ateapi/internal/authz/model_test.fga.yaml +++ b/cmd/ateapi/internal/authz/model_test.fga.yaml @@ -584,7 +584,7 @@ tests: assertions: can_mint_actor_jwt: false - - name: 10. External Volume Classes (Inherited from Global) + - name: 10. External Volume Classes & Access Policies check: - user: user:carol # Global owner object: global:root @@ -601,21 +601,54 @@ tests: assertions: can_create_external_volume_class: false can_list_external_volume_classes: false - - user: user:carol + - user: user:carol # Global owner manages class and its access policy object: external_volume_class:nfs-gold assertions: can_get: true can_delete: true - - user: user:frank + can_create_access_policy: true + can_get_access_policy: true + can_update_access_policy: true + can_delete_access_policy: true + - user: user:frank # Global viewer reads class and its access policy object: external_volume_class:nfs-gold assertions: can_get: true can_delete: false - - user: user:bob + can_create_access_policy: false + can_get_access_policy: true + can_update_access_policy: false + can_delete_access_policy: false + - user: user:alice # Owner of allowed atespace space-1 reads class, not its policy + object: external_volume_class:nfs-gold + assertions: + can_get: true + can_delete: false + can_create_access_policy: false + can_get_access_policy: false + can_update_access_policy: false + can_delete_access_policy: false + - user: user:bob # Editor of allowed atespace space-1 reads class, not its policy + object: external_volume_class:nfs-gold + assertions: + can_get: true + can_delete: false + can_create_access_policy: false + can_get_access_policy: false + can_update_access_policy: false + can_delete_access_policy: false + - user: user:bob # Editor of space-1 cannot read disallowed class + object: external_volume_class:ssd-restricted + assertions: + can_get: false + can_delete: false + can_get_access_policy: false + - user: user:dave # Viewer of allowed atespace space-1 cannot read class object: external_volume_class:nfs-gold assertions: can_get: false can_delete: false + can_get_access_policy: false - user: atespace:space-1 object: external_volume_class:nfs-gold assertions: From 3f7f2f927e5c496a967d227b44439d9f460306b1 Mon Sep 17 00:00:00 2001 From: Vu Le Date: Fri, 13 Nov 2026 19:28:29 +0000 Subject: [PATCH 29/30] add evc access policy protoRPCs, apivalidation and apitool tests Signed-off-by: Vu Le --- api/ateapi/v1/ateapi.pb.go | 931 ++++++++++++------ api/ateapi/v1/ateapi.proto | 108 +- api/ateapi/v1/ateapi_grpc.pb.go | 252 ++++- .../internal/apivalidation/access_policy.go | 70 +- .../apivalidation/access_policy_test.go | 342 +++++++ .../apivalidation/zz_generated.validation.go | 414 ++++++++ cmd/ateapi/internal/authz/registry.go | 12 + cmd/ateapi/internal/authz/registry_test.go | 48 + tools/apitool/internal/docsite/docsite.go | 11 +- .../apitool/internal/docsite/docsite_test.go | 21 +- tools/apitool/internal/docsite/pages.go | 8 +- tools/apitool/internal/docsite/pages_test.go | 18 +- tools/apitool/internal/examples/examples.go | 8 +- .../internal/examples/examples_test.go | 18 +- .../ExternalVolumeClass.AccessPolicy.yaml | 24 + tools/apitool/internal/model/model.go | 4 +- tools/apitool/internal/model/model_test.go | 15 +- 17 files changed, 1902 insertions(+), 402 deletions(-) create mode 100644 tools/apitool/internal/examples/grpc/ExternalVolumeClass.AccessPolicy.yaml diff --git a/api/ateapi/v1/ateapi.pb.go b/api/ateapi/v1/ateapi.pb.go index 36031253fe..e590e0b81b 100644 --- a/api/ateapi/v1/ateapi.pb.go +++ b/api/ateapi/v1/ateapi.pb.go @@ -9697,9 +9697,9 @@ func (x *SnapshotReport) GetDurableCompleteTime() *timestamppb.Timestamp { type AccessPolicy struct { state protoimpl.MessageState `protogen:"open.v1"` // Standard resource metadata. Atespace must match the parent resource (empty - // for global-scoped parents like Global and Atespace) and name must be - // "default". Both are caller-specified on create and immutable. UID, version, - // create_time, and update_time are server-managed. + // for global-scoped parents like Global, Atespace, and ExternalVolumeClass) + // and name must be "default". Both are caller-specified on create and + // immutable. UID, version, create_time, and update_time are server-managed. // // +k8s:required // +k8s:customValidation # name must be "default" @@ -9758,19 +9758,22 @@ func (x *AccessPolicy) GetBindings() []*Binding { return nil } -// Binding associates a list of principals (members) with a single role. +// Binding associates a list of members with a single role. type Binding struct { state protoimpl.MessageState `protogen:"open.v1"` // The role name for the parent resource type (e.g., "owner", "editor", - // "viewer"). + // "viewer", "allowed_atespace"). // // +k8s:required // +k8s:maxLength=64 Role string `protobuf:"bytes,1,opt,name=role,proto3" json:"role,omitempty"` - // Principal identities granted this role. + // Subjects granted this role: `user:` principals on Global ("owner", + // "viewer") and Atespace ("owner", "editor", "viewer") policies, or + // `atespace:` on ExternalVolumeClass ("allowed_atespace") policies. // Examples: // - "user:alice@example.com" // - "user:sa-ci-runner" + // - "atespace:team-a" // // +k8s:required // +k8s:listType=set @@ -10230,6 +10233,267 @@ func (x *DeleteAtespaceAccessPolicyRequest) GetOptions() *DeleteOptions { return nil } +// GetExternalVolumeClassAccessPolicyRequest identifies an ExternalVolumeClass's access policy. +type GetExternalVolumeClassAccessPolicyRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The parent ExternalVolumeClass of the access policy resource to retrieve. + // + // +k8s:required + // +k8s:beta(since: "0.0")=+k8s:subfield(atespace)=+k8s:forbidden # TODO: get rid of beta prefix + ExternalVolumeClass *ObjectRef `protobuf:"bytes,1,opt,name=external_volume_class,json=externalVolumeClass,proto3" json:"external_volume_class,omitempty"` + // Name of the singleton access policy. Must be "default". + // + // +k8s:required + // +k8s:format=k8s-short-name + // +k8s:customValidation # must be "default" + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetExternalVolumeClassAccessPolicyRequest) Reset() { + *x = GetExternalVolumeClassAccessPolicyRequest{} + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[144] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetExternalVolumeClassAccessPolicyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetExternalVolumeClassAccessPolicyRequest) ProtoMessage() {} + +func (x *GetExternalVolumeClassAccessPolicyRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[144] + 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 GetExternalVolumeClassAccessPolicyRequest.ProtoReflect.Descriptor instead. +func (*GetExternalVolumeClassAccessPolicyRequest) Descriptor() ([]byte, []int) { + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{144} +} + +func (x *GetExternalVolumeClassAccessPolicyRequest) GetExternalVolumeClass() *ObjectRef { + if x != nil { + return x.ExternalVolumeClass + } + return nil +} + +func (x *GetExternalVolumeClassAccessPolicyRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +// CreateExternalVolumeClassAccessPolicyRequest creates an access policy for an ExternalVolumeClass. +type CreateExternalVolumeClassAccessPolicyRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Parent ExternalVolumeClass under which to create the policy resource. + // + // +k8s:required + // +k8s:beta(since: "0.0")=+k8s:subfield(atespace)=+k8s:forbidden # TODO: get rid of beta prefix + ExternalVolumeClass *ObjectRef `protobuf:"bytes,1,opt,name=external_volume_class,json=externalVolumeClass,proto3" json:"external_volume_class,omitempty"` + // The policy to create. metadata.name must be "default" and + // metadata.atespace must be empty. + // + // +ate:preview=ExternalVolumes + // +k8s:ifDisabled(ExternalVolumes)=+k8s:forbidden + // +k8s:required + AccessPolicy *AccessPolicy `protobuf:"bytes,2,opt,name=access_policy,json=accessPolicy,proto3" json:"access_policy,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateExternalVolumeClassAccessPolicyRequest) Reset() { + *x = CreateExternalVolumeClassAccessPolicyRequest{} + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[145] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateExternalVolumeClassAccessPolicyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateExternalVolumeClassAccessPolicyRequest) ProtoMessage() {} + +func (x *CreateExternalVolumeClassAccessPolicyRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[145] + 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 CreateExternalVolumeClassAccessPolicyRequest.ProtoReflect.Descriptor instead. +func (*CreateExternalVolumeClassAccessPolicyRequest) Descriptor() ([]byte, []int) { + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{145} +} + +func (x *CreateExternalVolumeClassAccessPolicyRequest) GetExternalVolumeClass() *ObjectRef { + if x != nil { + return x.ExternalVolumeClass + } + return nil +} + +func (x *CreateExternalVolumeClassAccessPolicyRequest) GetAccessPolicy() *AccessPolicy { + if x != nil { + return x.AccessPolicy + } + return nil +} + +// UpdateExternalVolumeClassAccessPolicyRequest replaces an ExternalVolumeClass's access policy. +type UpdateExternalVolumeClassAccessPolicyRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Parent ExternalVolumeClass under which to update the policy resource. + // + // +k8s:required + // +k8s:beta(since: "0.0")=+k8s:subfield(atespace)=+k8s:forbidden # TODO: get rid of beta prefix + ExternalVolumeClass *ObjectRef `protobuf:"bytes,1,opt,name=external_volume_class,json=externalVolumeClass,proto3" json:"external_volume_class,omitempty"` + // Full replacement. Metadata UID and version are required preconditions; + // metadata.name must be "default" and metadata.atespace must be empty. + // + // +ate:preview=ExternalVolumes + // +k8s:ifDisabled(ExternalVolumes)=+k8s:forbidden + // +k8s:required + AccessPolicy *AccessPolicy `protobuf:"bytes,2,opt,name=access_policy,json=accessPolicy,proto3" json:"access_policy,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateExternalVolumeClassAccessPolicyRequest) Reset() { + *x = UpdateExternalVolumeClassAccessPolicyRequest{} + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[146] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateExternalVolumeClassAccessPolicyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateExternalVolumeClassAccessPolicyRequest) ProtoMessage() {} + +func (x *UpdateExternalVolumeClassAccessPolicyRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[146] + 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 UpdateExternalVolumeClassAccessPolicyRequest.ProtoReflect.Descriptor instead. +func (*UpdateExternalVolumeClassAccessPolicyRequest) Descriptor() ([]byte, []int) { + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{146} +} + +func (x *UpdateExternalVolumeClassAccessPolicyRequest) GetExternalVolumeClass() *ObjectRef { + if x != nil { + return x.ExternalVolumeClass + } + return nil +} + +func (x *UpdateExternalVolumeClassAccessPolicyRequest) GetAccessPolicy() *AccessPolicy { + if x != nil { + return x.AccessPolicy + } + return nil +} + +// DeleteExternalVolumeClassAccessPolicyRequest identifies an ExternalVolumeClass's access policy. +type DeleteExternalVolumeClassAccessPolicyRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The parent ExternalVolumeClass of the access policy resource to delete. + // + // +k8s:required + // +k8s:beta(since: "0.0")=+k8s:subfield(atespace)=+k8s:forbidden # TODO: get rid of beta prefix + ExternalVolumeClass *ObjectRef `protobuf:"bytes,1,opt,name=external_volume_class,json=externalVolumeClass,proto3" json:"external_volume_class,omitempty"` + // Name of the singleton access policy. Must be "default". + // + // +k8s:required + // +k8s:format=k8s-short-name + // +k8s:customValidation # must be "default" + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // Optional per-delete preconditions. + // + // +k8s:optional + Options *DeleteOptions `protobuf:"bytes,3,opt,name=options,proto3" json:"options,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DeleteExternalVolumeClassAccessPolicyRequest) Reset() { + *x = DeleteExternalVolumeClassAccessPolicyRequest{} + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[147] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteExternalVolumeClassAccessPolicyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteExternalVolumeClassAccessPolicyRequest) ProtoMessage() {} + +func (x *DeleteExternalVolumeClassAccessPolicyRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[147] + 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 DeleteExternalVolumeClassAccessPolicyRequest.ProtoReflect.Descriptor instead. +func (*DeleteExternalVolumeClassAccessPolicyRequest) Descriptor() ([]byte, []int) { + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{147} +} + +func (x *DeleteExternalVolumeClassAccessPolicyRequest) GetExternalVolumeClass() *ObjectRef { + if x != nil { + return x.ExternalVolumeClass + } + return nil +} + +func (x *DeleteExternalVolumeClassAccessPolicyRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *DeleteExternalVolumeClassAccessPolicyRequest) GetOptions() *DeleteOptions { + if x != nil { + return x.Options + } + return nil +} + // ResourceAnnotation marks a message as an API resource. See // docs/resource-model.md. type ResourceAnnotation struct { @@ -10252,7 +10516,7 @@ type ResourceAnnotation struct { func (x *ResourceAnnotation) Reset() { *x = ResourceAnnotation{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[144] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[148] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10264,7 +10528,7 @@ func (x *ResourceAnnotation) String() string { func (*ResourceAnnotation) ProtoMessage() {} func (x *ResourceAnnotation) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[144] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[148] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10277,7 +10541,7 @@ func (x *ResourceAnnotation) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceAnnotation.ProtoReflect.Descriptor instead. func (*ResourceAnnotation) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{144} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{148} } func (x *ResourceAnnotation) GetParents() []string { @@ -10320,7 +10584,7 @@ type MethodAnnotation struct { func (x *MethodAnnotation) Reset() { *x = MethodAnnotation{} - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[145] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[149] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10332,7 +10596,7 @@ func (x *MethodAnnotation) String() string { func (*MethodAnnotation) ProtoMessage() {} func (x *MethodAnnotation) ProtoReflect() protoreflect.Message { - mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[145] + mi := &file_api_ateapi_v1_ateapi_proto_msgTypes[149] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10345,7 +10609,7 @@ func (x *MethodAnnotation) ProtoReflect() protoreflect.Message { // Deprecated: Use MethodAnnotation.ProtoReflect.Descriptor instead. func (*MethodAnnotation) Descriptor() ([]byte, []int) { - return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{145} + return file_api_ateapi_v1_ateapi_proto_rawDescGZIP(), []int{149} } func (x *MethodAnnotation) GetResource() string { @@ -10879,12 +11143,13 @@ const file_api_ateapi_v1_ateapi_proto_rawDesc = "" + "\bfidelity\x18\x03 \x01(\x0e2%.substrate.ateapi.v1.SnapshotFidelityR\bfidelity\x12;\n" + "\x06object\x18\x04 \x01(\v2#.substrate.ateapi.v1.ObjectSnapshotR\x06object\x12F\n" + "\x11local_commit_time\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\x0flocalCommitTime\x12N\n" + - "\x15durable_complete_time\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\x13durableCompleteTime\"\xb5\x01\n" + + "\x15durable_complete_time\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\x13durableCompleteTime\"\xca\x01\n" + "\fAccessPolicy\x12A\n" + "\bmetadata\x18\x01 \x01(\v2%.substrate.ateapi.v1.ResourceMetadataR\bmetadata\x128\n" + - "\bbindings\x18\x02 \x03(\v2\x1c.substrate.ateapi.v1.BindingR\bbindings:(\x82\xb5\x18$\n" + + "\bbindings\x18\x02 \x03(\v2\x1c.substrate.ateapi.v1.BindingR\bbindings:=\x82\xb5\x189\n" + "\x06Global\n" + - "\bAtespace\x10\x01\"\x0eAccessPolicies\"7\n" + + "\bAtespace\n" + + "\x13ExternalVolumeClass\x10\x01\"\x0eAccessPolicies\"7\n" + "\aBinding\x12\x12\n" + "\x04role\x18\x01 \x01(\tR\x04role\x12\x18\n" + "\amembers\x18\x02 \x03(\tR\amembers\"2\n" + @@ -10906,6 +11171,19 @@ const file_api_ateapi_v1_ateapi_proto_rawDesc = "" + "!DeleteAtespaceAccessPolicyRequest\x12:\n" + "\batespace\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\batespace\x12\x12\n" + "\x04name\x18\x02 \x01(\tR\x04name\x12<\n" + + "\aoptions\x18\x03 \x01(\v2\".substrate.ateapi.v1.DeleteOptionsR\aoptions\"\x93\x01\n" + + ")GetExternalVolumeClassAccessPolicyRequest\x12R\n" + + "\x15external_volume_class\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x13externalVolumeClass\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\"\xca\x01\n" + + ",CreateExternalVolumeClassAccessPolicyRequest\x12R\n" + + "\x15external_volume_class\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x13externalVolumeClass\x12F\n" + + "\raccess_policy\x18\x02 \x01(\v2!.substrate.ateapi.v1.AccessPolicyR\faccessPolicy\"\xca\x01\n" + + ",UpdateExternalVolumeClassAccessPolicyRequest\x12R\n" + + "\x15external_volume_class\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x13externalVolumeClass\x12F\n" + + "\raccess_policy\x18\x02 \x01(\v2!.substrate.ateapi.v1.AccessPolicyR\faccessPolicy\"\xd4\x01\n" + + ",DeleteExternalVolumeClassAccessPolicyRequest\x12R\n" + + "\x15external_volume_class\x18\x01 \x01(\v2\x1e.substrate.ateapi.v1.ObjectRefR\x13externalVolumeClass\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12<\n" + "\aoptions\x18\x03 \x01(\v2\".substrate.ateapi.v1.DeleteOptionsR\aoptions\"\x96\x01\n" + "\x12ResourceAnnotation\x12\x18\n" + "\aparents\x18\x01 \x03(\tR\aparents\x12\x1c\n" + @@ -10962,7 +11240,7 @@ const file_api_ateapi_v1_ateapi_proto_rawDesc = "" + "\x05Scope\x12\x15\n" + "\x11SCOPE_UNSPECIFIED\x10\x00\x12\x12\n" + "\x0eSCOPE_ATESPACE\x10\x01\x12\x10\n" + - "\fSCOPE_GLOBAL\x10\x022\xba+\n" + + "\fSCOPE_GLOBAL\x10\x022\xc40\n" + "\aControl\x12Y\n" + "\bGetActor\x12$.substrate.ateapi.v1.GetActorRequest\x1a\x1a.substrate.ateapi.v1.Actor\"\v\x82\xb5\x18\a\n" + "\x05Actor\x12_\n" + @@ -11060,6 +11338,14 @@ const file_api_ateapi_v1_ateapi_proto_rawDesc = "" + "\x1aUpdateAtespaceAccessPolicy\x126.substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest\x1a!.substrate.ateapi.v1.AccessPolicy\"\x12\x82\xb5\x18\x0e\n" + "\fAccessPolicy\x12\x8b\x01\n" + "\x1aDeleteAtespaceAccessPolicy\x126.substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest\x1a!.substrate.ateapi.v1.AccessPolicy\"\x12\x82\xb5\x18\x0e\n" + + "\fAccessPolicy\x12\x9b\x01\n" + + "\"GetExternalVolumeClassAccessPolicy\x12>.substrate.ateapi.v1.GetExternalVolumeClassAccessPolicyRequest\x1a!.substrate.ateapi.v1.AccessPolicy\"\x12\x82\xb5\x18\x0e\n" + + "\fAccessPolicy\x12\xa1\x01\n" + + "%CreateExternalVolumeClassAccessPolicy\x12A.substrate.ateapi.v1.CreateExternalVolumeClassAccessPolicyRequest\x1a!.substrate.ateapi.v1.AccessPolicy\"\x12\x82\xb5\x18\x0e\n" + + "\fAccessPolicy\x12\xa1\x01\n" + + "%UpdateExternalVolumeClassAccessPolicy\x12A.substrate.ateapi.v1.UpdateExternalVolumeClassAccessPolicyRequest\x1a!.substrate.ateapi.v1.AccessPolicy\"\x12\x82\xb5\x18\x0e\n" + + "\fAccessPolicy\x12\xa1\x01\n" + + "%DeleteExternalVolumeClassAccessPolicy\x12A.substrate.ateapi.v1.DeleteExternalVolumeClassAccessPolicyRequest\x1a!.substrate.ateapi.v1.AccessPolicy\"\x12\x82\xb5\x18\x0e\n" + "\fAccessPolicy2\xfd\a\n" + "\rWorkerService\x12u\n" + "\x12AcquireWorkerEpoch\x12..substrate.ateapi.v1.AcquireWorkerEpochRequest\x1a/.substrate.ateapi.v1.AcquireWorkerEpochResponse\x12i\n" + @@ -11086,171 +11372,175 @@ func file_api_ateapi_v1_ateapi_proto_rawDescGZIP() []byte { } var file_api_ateapi_v1_ateapi_proto_enumTypes = make([]protoimpl.EnumInfo, 10) -var file_api_ateapi_v1_ateapi_proto_msgTypes = make([]protoimpl.MessageInfo, 150) +var file_api_ateapi_v1_ateapi_proto_msgTypes = make([]protoimpl.MessageInfo, 154) var file_api_ateapi_v1_ateapi_proto_goTypes = []any{ - (SnapshotOwner)(0), // 0: substrate.ateapi.v1.SnapshotOwner - (SnapshotStorageState)(0), // 1: substrate.ateapi.v1.SnapshotStorageState - (SnapshotFidelity)(0), // 2: substrate.ateapi.v1.SnapshotFidelity - (TagScope)(0), // 3: substrate.ateapi.v1.TagScope - (ActorState)(0), // 4: substrate.ateapi.v1.ActorState - (GoldenSnapshotMode)(0), // 5: substrate.ateapi.v1.GoldenSnapshotMode - (ActorMetadataField)(0), // 6: substrate.ateapi.v1.ActorMetadataField - (DurabilityMode)(0), // 7: substrate.ateapi.v1.DurabilityMode - (WorkerState)(0), // 8: substrate.ateapi.v1.WorkerState - (Scope)(0), // 9: substrate.ateapi.v1.Scope - (*ObjectSnapshot)(nil), // 10: substrate.ateapi.v1.ObjectSnapshot - (*SnapshotStorage)(nil), // 11: substrate.ateapi.v1.SnapshotStorage - (*Snapshot)(nil), // 12: substrate.ateapi.v1.Snapshot - (*Selector)(nil), // 13: substrate.ateapi.v1.Selector - (*ResourceMetadata)(nil), // 14: substrate.ateapi.v1.ResourceMetadata - (*ExternalVolumes)(nil), // 15: substrate.ateapi.v1.ExternalVolumes - (*ExternalVolumeStatus)(nil), // 16: substrate.ateapi.v1.ExternalVolumeStatus - (*Actor)(nil), // 17: substrate.ateapi.v1.Actor - (*EgressPolicy)(nil), // 18: substrate.ateapi.v1.EgressPolicy - (*EgressPolicyTemplate)(nil), // 19: substrate.ateapi.v1.EgressPolicyTemplate - (*EgressRule)(nil), // 20: substrate.ateapi.v1.EgressRule - (*HttpRule)(nil), // 21: substrate.ateapi.v1.HttpRule - (*HttpsRule)(nil), // 22: substrate.ateapi.v1.HttpsRule - (*TlsPassthroughRule)(nil), // 23: substrate.ateapi.v1.TlsPassthroughRule - (*Ports)(nil), // 24: substrate.ateapi.v1.Ports - (*AllPorts)(nil), // 25: substrate.ateapi.v1.AllPorts - (*HttpRuleEffects)(nil), // 26: substrate.ateapi.v1.HttpRuleEffects - (*CredentialHeader)(nil), // 27: substrate.ateapi.v1.CredentialHeader - (*ActorJwtSource)(nil), // 28: substrate.ateapi.v1.ActorJwtSource - (*ActorStatus)(nil), // 29: substrate.ateapi.v1.ActorStatus - (*ActorCrash)(nil), // 30: substrate.ateapi.v1.ActorCrash - (*WorkerAssignment)(nil), // 31: substrate.ateapi.v1.WorkerAssignment - (*TagStatus)(nil), // 32: substrate.ateapi.v1.TagStatus - (*Tag)(nil), // 33: substrate.ateapi.v1.Tag - (*Atespace)(nil), // 34: substrate.ateapi.v1.Atespace - (*ObjectRef)(nil), // 35: substrate.ateapi.v1.ObjectRef - (*ActorTemplate)(nil), // 36: substrate.ateapi.v1.ActorTemplate - (*ResourceRequirements)(nil), // 37: substrate.ateapi.v1.ResourceRequirements - (*Resources)(nil), // 38: substrate.ateapi.v1.Resources - (*GoldenSnapshotStatus)(nil), // 39: substrate.ateapi.v1.GoldenSnapshotStatus - (*ActorTemplateStatus)(nil), // 40: substrate.ateapi.v1.ActorTemplateStatus - (*SnapshotConfig)(nil), // 41: substrate.ateapi.v1.SnapshotConfig - (*GoldenSnapshotConfig)(nil), // 42: substrate.ateapi.v1.GoldenSnapshotConfig - (*Container)(nil), // 43: substrate.ateapi.v1.Container - (*SecurityContext)(nil), // 44: substrate.ateapi.v1.SecurityContext - (*Capabilities)(nil), // 45: substrate.ateapi.v1.Capabilities - (*EnvVar)(nil), // 46: substrate.ateapi.v1.EnvVar - (*WakeupProbe)(nil), // 47: substrate.ateapi.v1.WakeupProbe - (*HttpGetAction)(nil), // 48: substrate.ateapi.v1.HttpGetAction - (*Volume)(nil), // 49: substrate.ateapi.v1.Volume - (*ExternalVolumeSource)(nil), // 50: substrate.ateapi.v1.ExternalVolumeSource - (*ImageVolumeSource)(nil), // 51: substrate.ateapi.v1.ImageVolumeSource - (*DurableDirVolumeSource)(nil), // 52: substrate.ateapi.v1.DurableDirVolumeSource - (*ExternalVolumeTemplate)(nil), // 53: substrate.ateapi.v1.ExternalVolumeTemplate - (*ExternalVolumeClass)(nil), // 54: substrate.ateapi.v1.ExternalVolumeClass - (*SystemInfoVolumeSource)(nil), // 55: substrate.ateapi.v1.SystemInfoVolumeSource - (*SystemInfoDataSource)(nil), // 56: substrate.ateapi.v1.SystemInfoDataSource - (*ActorMetadataDataSource)(nil), // 57: substrate.ateapi.v1.ActorMetadataDataSource - (*ActorMetadataItem)(nil), // 58: substrate.ateapi.v1.ActorMetadataItem - (*TrustBundleDataSource)(nil), // 59: substrate.ateapi.v1.TrustBundleDataSource - (*VolumeMount)(nil), // 60: substrate.ateapi.v1.VolumeMount - (*CreateAtespaceRequest)(nil), // 61: substrate.ateapi.v1.CreateAtespaceRequest - (*GetAtespaceRequest)(nil), // 62: substrate.ateapi.v1.GetAtespaceRequest - (*ListAtespacesRequest)(nil), // 63: substrate.ateapi.v1.ListAtespacesRequest - (*ListAtespacesResponse)(nil), // 64: substrate.ateapi.v1.ListAtespacesResponse - (*DeleteAtespaceRequest)(nil), // 65: substrate.ateapi.v1.DeleteAtespaceRequest - (*CreateExternalVolumeClassRequest)(nil), // 66: substrate.ateapi.v1.CreateExternalVolumeClassRequest - (*GetExternalVolumeClassRequest)(nil), // 67: substrate.ateapi.v1.GetExternalVolumeClassRequest - (*ListExternalVolumeClassesRequest)(nil), // 68: substrate.ateapi.v1.ListExternalVolumeClassesRequest - (*ListExternalVolumeClassesResponse)(nil), // 69: substrate.ateapi.v1.ListExternalVolumeClassesResponse - (*DeleteExternalVolumeClassRequest)(nil), // 70: substrate.ateapi.v1.DeleteExternalVolumeClassRequest - (*CreateActorTemplateRequest)(nil), // 71: substrate.ateapi.v1.CreateActorTemplateRequest - (*GetActorTemplateRequest)(nil), // 72: substrate.ateapi.v1.GetActorTemplateRequest - (*ListActorTemplatesRequest)(nil), // 73: substrate.ateapi.v1.ListActorTemplatesRequest - (*ListActorTemplatesResponse)(nil), // 74: substrate.ateapi.v1.ListActorTemplatesResponse - (*DeleteActorTemplateRequest)(nil), // 75: substrate.ateapi.v1.DeleteActorTemplateRequest - (*GetActorRequest)(nil), // 76: substrate.ateapi.v1.GetActorRequest - (*CreateActorRequest)(nil), // 77: substrate.ateapi.v1.CreateActorRequest - (*UpdateActorRequest)(nil), // 78: substrate.ateapi.v1.UpdateActorRequest - (*SuspendActorRequest)(nil), // 79: substrate.ateapi.v1.SuspendActorRequest - (*SuspendActorResponse)(nil), // 80: substrate.ateapi.v1.SuspendActorResponse - (*SuspendOptions)(nil), // 81: substrate.ateapi.v1.SuspendOptions - (*ResumeActorRequest)(nil), // 82: substrate.ateapi.v1.ResumeActorRequest - (*ResumeActorResponse)(nil), // 83: substrate.ateapi.v1.ResumeActorResponse - (*RevertActorRequest)(nil), // 84: substrate.ateapi.v1.RevertActorRequest - (*RevertActorResponse)(nil), // 85: substrate.ateapi.v1.RevertActorResponse - (*DeleteActorRequest)(nil), // 86: substrate.ateapi.v1.DeleteActorRequest - (*GetActorEgressPolicyRequest)(nil), // 87: substrate.ateapi.v1.GetActorEgressPolicyRequest - (*CreateActorEgressPolicyRequest)(nil), // 88: substrate.ateapi.v1.CreateActorEgressPolicyRequest - (*UpdateActorEgressPolicyRequest)(nil), // 89: substrate.ateapi.v1.UpdateActorEgressPolicyRequest - (*DeleteActorEgressPolicyRequest)(nil), // 90: substrate.ateapi.v1.DeleteActorEgressPolicyRequest - (*GetTagRequest)(nil), // 91: substrate.ateapi.v1.GetTagRequest - (*MintActorJwtRequest)(nil), // 92: substrate.ateapi.v1.MintActorJwtRequest - (*MintActorJwtResponse)(nil), // 93: substrate.ateapi.v1.MintActorJwtResponse - (*ListTagsRequest)(nil), // 94: substrate.ateapi.v1.ListTagsRequest - (*ListTagsResponse)(nil), // 95: substrate.ateapi.v1.ListTagsResponse - (*CreateTagRequest)(nil), // 96: substrate.ateapi.v1.CreateTagRequest - (*UpdateTagRequest)(nil), // 97: substrate.ateapi.v1.UpdateTagRequest - (*DeleteTagRequest)(nil), // 98: substrate.ateapi.v1.DeleteTagRequest - (*DeleteOptions)(nil), // 99: substrate.ateapi.v1.DeleteOptions - (*ListOptions)(nil), // 100: substrate.ateapi.v1.ListOptions - (*ListWorkerActorAssignmentsRequest)(nil), // 101: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest - (*ListWorkerActorAssignmentsResponse)(nil), // 102: substrate.ateapi.v1.ListWorkerActorAssignmentsResponse - (*ListWorkersRequest)(nil), // 103: substrate.ateapi.v1.ListWorkersRequest - (*ListWorkersResponse)(nil), // 104: substrate.ateapi.v1.ListWorkersResponse - (*GetWorkerRequest)(nil), // 105: substrate.ateapi.v1.GetWorkerRequest - (*CreateWorkerRequest)(nil), // 106: substrate.ateapi.v1.CreateWorkerRequest - (*UpdateWorkerRequest)(nil), // 107: substrate.ateapi.v1.UpdateWorkerRequest - (*DeleteWorkerRequest)(nil), // 108: substrate.ateapi.v1.DeleteWorkerRequest - (*DrainWorkerRequest)(nil), // 109: substrate.ateapi.v1.DrainWorkerRequest - (*DrainWorkerResponse)(nil), // 110: substrate.ateapi.v1.DrainWorkerResponse - (*MarkWorkerAvailableRequest)(nil), // 111: substrate.ateapi.v1.MarkWorkerAvailableRequest - (*MarkWorkerAvailableResponse)(nil), // 112: substrate.ateapi.v1.MarkWorkerAvailableResponse - (*MarkWorkerUnavailableRequest)(nil), // 113: substrate.ateapi.v1.MarkWorkerUnavailableRequest - (*MarkWorkerUnavailableResponse)(nil), // 114: substrate.ateapi.v1.MarkWorkerUnavailableResponse - (*ListActorsRequest)(nil), // 115: substrate.ateapi.v1.ListActorsRequest - (*ListActorsResponse)(nil), // 116: substrate.ateapi.v1.ListActorsResponse - (*Worker)(nil), // 117: substrate.ateapi.v1.Worker - (*WorkerStatus)(nil), // 118: substrate.ateapi.v1.WorkerStatus - (*WorkerSandboxClass)(nil), // 119: substrate.ateapi.v1.WorkerSandboxClass - (*WorkerSandboxRuntime)(nil), // 120: substrate.ateapi.v1.WorkerSandboxRuntime - (*RuntimeOverhead)(nil), // 121: substrate.ateapi.v1.RuntimeOverhead - (*ActorSandboxRuntime)(nil), // 122: substrate.ateapi.v1.ActorSandboxRuntime - (*VersionedSandboxCompat)(nil), // 123: substrate.ateapi.v1.VersionedSandboxCompat - (*AttributeEntry)(nil), // 124: substrate.ateapi.v1.AttributeEntry - (*WorkerResources)(nil), // 125: substrate.ateapi.v1.WorkerResources - (*ActorAssignment)(nil), // 126: substrate.ateapi.v1.ActorAssignment - (*AcquireWorkerEpochRequest)(nil), // 127: substrate.ateapi.v1.AcquireWorkerEpochRequest - (*AcquireWorkerEpochResponse)(nil), // 128: substrate.ateapi.v1.AcquireWorkerEpochResponse - (*RegisterWorkerRequest)(nil), // 129: substrate.ateapi.v1.RegisterWorkerRequest - (*RegisterWorkerResponse)(nil), // 130: substrate.ateapi.v1.RegisterWorkerResponse - (*SetWorkerSandboxRuntimesRequest)(nil), // 131: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest - (*SetWorkerSandboxRuntimesResponse)(nil), // 132: substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse - (*MintWorkerActorCertificateRequest)(nil), // 133: substrate.ateapi.v1.MintWorkerActorCertificateRequest - (*MintWorkerActorCertificateResponse)(nil), // 134: substrate.ateapi.v1.MintWorkerActorCertificateResponse - (*MintWorkerActorJwtRequest)(nil), // 135: substrate.ateapi.v1.MintWorkerActorJwtRequest - (*MintWorkerActorJwtResponse)(nil), // 136: substrate.ateapi.v1.MintWorkerActorJwtResponse - (*RequestActorSuspendRequest)(nil), // 137: substrate.ateapi.v1.RequestActorSuspendRequest - (*RequestActorSuspendResponse)(nil), // 138: substrate.ateapi.v1.RequestActorSuspendResponse - (*ReportActorCrashedRequest)(nil), // 139: substrate.ateapi.v1.ReportActorCrashedRequest - (*ReportActorCrashedResponse)(nil), // 140: substrate.ateapi.v1.ReportActorCrashedResponse - (*ReportActorSnapshotStateRequest)(nil), // 141: substrate.ateapi.v1.ReportActorSnapshotStateRequest - (*ReportActorSnapshotStateResponse)(nil), // 142: substrate.ateapi.v1.ReportActorSnapshotStateResponse - (*ActorSnapshotState)(nil), // 143: substrate.ateapi.v1.ActorSnapshotState - (*SnapshotReport)(nil), // 144: substrate.ateapi.v1.SnapshotReport - (*AccessPolicy)(nil), // 145: substrate.ateapi.v1.AccessPolicy - (*Binding)(nil), // 146: substrate.ateapi.v1.Binding - (*GetGlobalAccessPolicyRequest)(nil), // 147: substrate.ateapi.v1.GetGlobalAccessPolicyRequest - (*CreateGlobalAccessPolicyRequest)(nil), // 148: substrate.ateapi.v1.CreateGlobalAccessPolicyRequest - (*UpdateGlobalAccessPolicyRequest)(nil), // 149: substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest - (*GetAtespaceAccessPolicyRequest)(nil), // 150: substrate.ateapi.v1.GetAtespaceAccessPolicyRequest - (*CreateAtespaceAccessPolicyRequest)(nil), // 151: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest - (*UpdateAtespaceAccessPolicyRequest)(nil), // 152: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest - (*DeleteAtespaceAccessPolicyRequest)(nil), // 153: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest - (*ResourceAnnotation)(nil), // 154: substrate.ateapi.v1.ResourceAnnotation - (*MethodAnnotation)(nil), // 155: substrate.ateapi.v1.MethodAnnotation - nil, // 156: substrate.ateapi.v1.Selector.MatchLabelsEntry - nil, // 157: substrate.ateapi.v1.ExternalVolumeStatus.VolumeContextEntry - nil, // 158: substrate.ateapi.v1.ExternalVolumeClass.ParametersEntry - nil, // 159: substrate.ateapi.v1.Worker.LabelsEntry - (*timestamppb.Timestamp)(nil), // 160: google.protobuf.Timestamp - (*descriptorpb.MessageOptions)(nil), // 161: google.protobuf.MessageOptions - (*descriptorpb.MethodOptions)(nil), // 162: google.protobuf.MethodOptions + (SnapshotOwner)(0), // 0: substrate.ateapi.v1.SnapshotOwner + (SnapshotStorageState)(0), // 1: substrate.ateapi.v1.SnapshotStorageState + (SnapshotFidelity)(0), // 2: substrate.ateapi.v1.SnapshotFidelity + (TagScope)(0), // 3: substrate.ateapi.v1.TagScope + (ActorState)(0), // 4: substrate.ateapi.v1.ActorState + (GoldenSnapshotMode)(0), // 5: substrate.ateapi.v1.GoldenSnapshotMode + (ActorMetadataField)(0), // 6: substrate.ateapi.v1.ActorMetadataField + (DurabilityMode)(0), // 7: substrate.ateapi.v1.DurabilityMode + (WorkerState)(0), // 8: substrate.ateapi.v1.WorkerState + (Scope)(0), // 9: substrate.ateapi.v1.Scope + (*ObjectSnapshot)(nil), // 10: substrate.ateapi.v1.ObjectSnapshot + (*SnapshotStorage)(nil), // 11: substrate.ateapi.v1.SnapshotStorage + (*Snapshot)(nil), // 12: substrate.ateapi.v1.Snapshot + (*Selector)(nil), // 13: substrate.ateapi.v1.Selector + (*ResourceMetadata)(nil), // 14: substrate.ateapi.v1.ResourceMetadata + (*ExternalVolumes)(nil), // 15: substrate.ateapi.v1.ExternalVolumes + (*ExternalVolumeStatus)(nil), // 16: substrate.ateapi.v1.ExternalVolumeStatus + (*Actor)(nil), // 17: substrate.ateapi.v1.Actor + (*EgressPolicy)(nil), // 18: substrate.ateapi.v1.EgressPolicy + (*EgressPolicyTemplate)(nil), // 19: substrate.ateapi.v1.EgressPolicyTemplate + (*EgressRule)(nil), // 20: substrate.ateapi.v1.EgressRule + (*HttpRule)(nil), // 21: substrate.ateapi.v1.HttpRule + (*HttpsRule)(nil), // 22: substrate.ateapi.v1.HttpsRule + (*TlsPassthroughRule)(nil), // 23: substrate.ateapi.v1.TlsPassthroughRule + (*Ports)(nil), // 24: substrate.ateapi.v1.Ports + (*AllPorts)(nil), // 25: substrate.ateapi.v1.AllPorts + (*HttpRuleEffects)(nil), // 26: substrate.ateapi.v1.HttpRuleEffects + (*CredentialHeader)(nil), // 27: substrate.ateapi.v1.CredentialHeader + (*ActorJwtSource)(nil), // 28: substrate.ateapi.v1.ActorJwtSource + (*ActorStatus)(nil), // 29: substrate.ateapi.v1.ActorStatus + (*ActorCrash)(nil), // 30: substrate.ateapi.v1.ActorCrash + (*WorkerAssignment)(nil), // 31: substrate.ateapi.v1.WorkerAssignment + (*TagStatus)(nil), // 32: substrate.ateapi.v1.TagStatus + (*Tag)(nil), // 33: substrate.ateapi.v1.Tag + (*Atespace)(nil), // 34: substrate.ateapi.v1.Atespace + (*ObjectRef)(nil), // 35: substrate.ateapi.v1.ObjectRef + (*ActorTemplate)(nil), // 36: substrate.ateapi.v1.ActorTemplate + (*ResourceRequirements)(nil), // 37: substrate.ateapi.v1.ResourceRequirements + (*Resources)(nil), // 38: substrate.ateapi.v1.Resources + (*GoldenSnapshotStatus)(nil), // 39: substrate.ateapi.v1.GoldenSnapshotStatus + (*ActorTemplateStatus)(nil), // 40: substrate.ateapi.v1.ActorTemplateStatus + (*SnapshotConfig)(nil), // 41: substrate.ateapi.v1.SnapshotConfig + (*GoldenSnapshotConfig)(nil), // 42: substrate.ateapi.v1.GoldenSnapshotConfig + (*Container)(nil), // 43: substrate.ateapi.v1.Container + (*SecurityContext)(nil), // 44: substrate.ateapi.v1.SecurityContext + (*Capabilities)(nil), // 45: substrate.ateapi.v1.Capabilities + (*EnvVar)(nil), // 46: substrate.ateapi.v1.EnvVar + (*WakeupProbe)(nil), // 47: substrate.ateapi.v1.WakeupProbe + (*HttpGetAction)(nil), // 48: substrate.ateapi.v1.HttpGetAction + (*Volume)(nil), // 49: substrate.ateapi.v1.Volume + (*ExternalVolumeSource)(nil), // 50: substrate.ateapi.v1.ExternalVolumeSource + (*ImageVolumeSource)(nil), // 51: substrate.ateapi.v1.ImageVolumeSource + (*DurableDirVolumeSource)(nil), // 52: substrate.ateapi.v1.DurableDirVolumeSource + (*ExternalVolumeTemplate)(nil), // 53: substrate.ateapi.v1.ExternalVolumeTemplate + (*ExternalVolumeClass)(nil), // 54: substrate.ateapi.v1.ExternalVolumeClass + (*SystemInfoVolumeSource)(nil), // 55: substrate.ateapi.v1.SystemInfoVolumeSource + (*SystemInfoDataSource)(nil), // 56: substrate.ateapi.v1.SystemInfoDataSource + (*ActorMetadataDataSource)(nil), // 57: substrate.ateapi.v1.ActorMetadataDataSource + (*ActorMetadataItem)(nil), // 58: substrate.ateapi.v1.ActorMetadataItem + (*TrustBundleDataSource)(nil), // 59: substrate.ateapi.v1.TrustBundleDataSource + (*VolumeMount)(nil), // 60: substrate.ateapi.v1.VolumeMount + (*CreateAtespaceRequest)(nil), // 61: substrate.ateapi.v1.CreateAtespaceRequest + (*GetAtespaceRequest)(nil), // 62: substrate.ateapi.v1.GetAtespaceRequest + (*ListAtespacesRequest)(nil), // 63: substrate.ateapi.v1.ListAtespacesRequest + (*ListAtespacesResponse)(nil), // 64: substrate.ateapi.v1.ListAtespacesResponse + (*DeleteAtespaceRequest)(nil), // 65: substrate.ateapi.v1.DeleteAtespaceRequest + (*CreateExternalVolumeClassRequest)(nil), // 66: substrate.ateapi.v1.CreateExternalVolumeClassRequest + (*GetExternalVolumeClassRequest)(nil), // 67: substrate.ateapi.v1.GetExternalVolumeClassRequest + (*ListExternalVolumeClassesRequest)(nil), // 68: substrate.ateapi.v1.ListExternalVolumeClassesRequest + (*ListExternalVolumeClassesResponse)(nil), // 69: substrate.ateapi.v1.ListExternalVolumeClassesResponse + (*DeleteExternalVolumeClassRequest)(nil), // 70: substrate.ateapi.v1.DeleteExternalVolumeClassRequest + (*CreateActorTemplateRequest)(nil), // 71: substrate.ateapi.v1.CreateActorTemplateRequest + (*GetActorTemplateRequest)(nil), // 72: substrate.ateapi.v1.GetActorTemplateRequest + (*ListActorTemplatesRequest)(nil), // 73: substrate.ateapi.v1.ListActorTemplatesRequest + (*ListActorTemplatesResponse)(nil), // 74: substrate.ateapi.v1.ListActorTemplatesResponse + (*DeleteActorTemplateRequest)(nil), // 75: substrate.ateapi.v1.DeleteActorTemplateRequest + (*GetActorRequest)(nil), // 76: substrate.ateapi.v1.GetActorRequest + (*CreateActorRequest)(nil), // 77: substrate.ateapi.v1.CreateActorRequest + (*UpdateActorRequest)(nil), // 78: substrate.ateapi.v1.UpdateActorRequest + (*SuspendActorRequest)(nil), // 79: substrate.ateapi.v1.SuspendActorRequest + (*SuspendActorResponse)(nil), // 80: substrate.ateapi.v1.SuspendActorResponse + (*SuspendOptions)(nil), // 81: substrate.ateapi.v1.SuspendOptions + (*ResumeActorRequest)(nil), // 82: substrate.ateapi.v1.ResumeActorRequest + (*ResumeActorResponse)(nil), // 83: substrate.ateapi.v1.ResumeActorResponse + (*RevertActorRequest)(nil), // 84: substrate.ateapi.v1.RevertActorRequest + (*RevertActorResponse)(nil), // 85: substrate.ateapi.v1.RevertActorResponse + (*DeleteActorRequest)(nil), // 86: substrate.ateapi.v1.DeleteActorRequest + (*GetActorEgressPolicyRequest)(nil), // 87: substrate.ateapi.v1.GetActorEgressPolicyRequest + (*CreateActorEgressPolicyRequest)(nil), // 88: substrate.ateapi.v1.CreateActorEgressPolicyRequest + (*UpdateActorEgressPolicyRequest)(nil), // 89: substrate.ateapi.v1.UpdateActorEgressPolicyRequest + (*DeleteActorEgressPolicyRequest)(nil), // 90: substrate.ateapi.v1.DeleteActorEgressPolicyRequest + (*GetTagRequest)(nil), // 91: substrate.ateapi.v1.GetTagRequest + (*MintActorJwtRequest)(nil), // 92: substrate.ateapi.v1.MintActorJwtRequest + (*MintActorJwtResponse)(nil), // 93: substrate.ateapi.v1.MintActorJwtResponse + (*ListTagsRequest)(nil), // 94: substrate.ateapi.v1.ListTagsRequest + (*ListTagsResponse)(nil), // 95: substrate.ateapi.v1.ListTagsResponse + (*CreateTagRequest)(nil), // 96: substrate.ateapi.v1.CreateTagRequest + (*UpdateTagRequest)(nil), // 97: substrate.ateapi.v1.UpdateTagRequest + (*DeleteTagRequest)(nil), // 98: substrate.ateapi.v1.DeleteTagRequest + (*DeleteOptions)(nil), // 99: substrate.ateapi.v1.DeleteOptions + (*ListOptions)(nil), // 100: substrate.ateapi.v1.ListOptions + (*ListWorkerActorAssignmentsRequest)(nil), // 101: substrate.ateapi.v1.ListWorkerActorAssignmentsRequest + (*ListWorkerActorAssignmentsResponse)(nil), // 102: substrate.ateapi.v1.ListWorkerActorAssignmentsResponse + (*ListWorkersRequest)(nil), // 103: substrate.ateapi.v1.ListWorkersRequest + (*ListWorkersResponse)(nil), // 104: substrate.ateapi.v1.ListWorkersResponse + (*GetWorkerRequest)(nil), // 105: substrate.ateapi.v1.GetWorkerRequest + (*CreateWorkerRequest)(nil), // 106: substrate.ateapi.v1.CreateWorkerRequest + (*UpdateWorkerRequest)(nil), // 107: substrate.ateapi.v1.UpdateWorkerRequest + (*DeleteWorkerRequest)(nil), // 108: substrate.ateapi.v1.DeleteWorkerRequest + (*DrainWorkerRequest)(nil), // 109: substrate.ateapi.v1.DrainWorkerRequest + (*DrainWorkerResponse)(nil), // 110: substrate.ateapi.v1.DrainWorkerResponse + (*MarkWorkerAvailableRequest)(nil), // 111: substrate.ateapi.v1.MarkWorkerAvailableRequest + (*MarkWorkerAvailableResponse)(nil), // 112: substrate.ateapi.v1.MarkWorkerAvailableResponse + (*MarkWorkerUnavailableRequest)(nil), // 113: substrate.ateapi.v1.MarkWorkerUnavailableRequest + (*MarkWorkerUnavailableResponse)(nil), // 114: substrate.ateapi.v1.MarkWorkerUnavailableResponse + (*ListActorsRequest)(nil), // 115: substrate.ateapi.v1.ListActorsRequest + (*ListActorsResponse)(nil), // 116: substrate.ateapi.v1.ListActorsResponse + (*Worker)(nil), // 117: substrate.ateapi.v1.Worker + (*WorkerStatus)(nil), // 118: substrate.ateapi.v1.WorkerStatus + (*WorkerSandboxClass)(nil), // 119: substrate.ateapi.v1.WorkerSandboxClass + (*WorkerSandboxRuntime)(nil), // 120: substrate.ateapi.v1.WorkerSandboxRuntime + (*RuntimeOverhead)(nil), // 121: substrate.ateapi.v1.RuntimeOverhead + (*ActorSandboxRuntime)(nil), // 122: substrate.ateapi.v1.ActorSandboxRuntime + (*VersionedSandboxCompat)(nil), // 123: substrate.ateapi.v1.VersionedSandboxCompat + (*AttributeEntry)(nil), // 124: substrate.ateapi.v1.AttributeEntry + (*WorkerResources)(nil), // 125: substrate.ateapi.v1.WorkerResources + (*ActorAssignment)(nil), // 126: substrate.ateapi.v1.ActorAssignment + (*AcquireWorkerEpochRequest)(nil), // 127: substrate.ateapi.v1.AcquireWorkerEpochRequest + (*AcquireWorkerEpochResponse)(nil), // 128: substrate.ateapi.v1.AcquireWorkerEpochResponse + (*RegisterWorkerRequest)(nil), // 129: substrate.ateapi.v1.RegisterWorkerRequest + (*RegisterWorkerResponse)(nil), // 130: substrate.ateapi.v1.RegisterWorkerResponse + (*SetWorkerSandboxRuntimesRequest)(nil), // 131: substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest + (*SetWorkerSandboxRuntimesResponse)(nil), // 132: substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse + (*MintWorkerActorCertificateRequest)(nil), // 133: substrate.ateapi.v1.MintWorkerActorCertificateRequest + (*MintWorkerActorCertificateResponse)(nil), // 134: substrate.ateapi.v1.MintWorkerActorCertificateResponse + (*MintWorkerActorJwtRequest)(nil), // 135: substrate.ateapi.v1.MintWorkerActorJwtRequest + (*MintWorkerActorJwtResponse)(nil), // 136: substrate.ateapi.v1.MintWorkerActorJwtResponse + (*RequestActorSuspendRequest)(nil), // 137: substrate.ateapi.v1.RequestActorSuspendRequest + (*RequestActorSuspendResponse)(nil), // 138: substrate.ateapi.v1.RequestActorSuspendResponse + (*ReportActorCrashedRequest)(nil), // 139: substrate.ateapi.v1.ReportActorCrashedRequest + (*ReportActorCrashedResponse)(nil), // 140: substrate.ateapi.v1.ReportActorCrashedResponse + (*ReportActorSnapshotStateRequest)(nil), // 141: substrate.ateapi.v1.ReportActorSnapshotStateRequest + (*ReportActorSnapshotStateResponse)(nil), // 142: substrate.ateapi.v1.ReportActorSnapshotStateResponse + (*ActorSnapshotState)(nil), // 143: substrate.ateapi.v1.ActorSnapshotState + (*SnapshotReport)(nil), // 144: substrate.ateapi.v1.SnapshotReport + (*AccessPolicy)(nil), // 145: substrate.ateapi.v1.AccessPolicy + (*Binding)(nil), // 146: substrate.ateapi.v1.Binding + (*GetGlobalAccessPolicyRequest)(nil), // 147: substrate.ateapi.v1.GetGlobalAccessPolicyRequest + (*CreateGlobalAccessPolicyRequest)(nil), // 148: substrate.ateapi.v1.CreateGlobalAccessPolicyRequest + (*UpdateGlobalAccessPolicyRequest)(nil), // 149: substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest + (*GetAtespaceAccessPolicyRequest)(nil), // 150: substrate.ateapi.v1.GetAtespaceAccessPolicyRequest + (*CreateAtespaceAccessPolicyRequest)(nil), // 151: substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest + (*UpdateAtespaceAccessPolicyRequest)(nil), // 152: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest + (*DeleteAtespaceAccessPolicyRequest)(nil), // 153: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest + (*GetExternalVolumeClassAccessPolicyRequest)(nil), // 154: substrate.ateapi.v1.GetExternalVolumeClassAccessPolicyRequest + (*CreateExternalVolumeClassAccessPolicyRequest)(nil), // 155: substrate.ateapi.v1.CreateExternalVolumeClassAccessPolicyRequest + (*UpdateExternalVolumeClassAccessPolicyRequest)(nil), // 156: substrate.ateapi.v1.UpdateExternalVolumeClassAccessPolicyRequest + (*DeleteExternalVolumeClassAccessPolicyRequest)(nil), // 157: substrate.ateapi.v1.DeleteExternalVolumeClassAccessPolicyRequest + (*ResourceAnnotation)(nil), // 158: substrate.ateapi.v1.ResourceAnnotation + (*MethodAnnotation)(nil), // 159: substrate.ateapi.v1.MethodAnnotation + nil, // 160: substrate.ateapi.v1.Selector.MatchLabelsEntry + nil, // 161: substrate.ateapi.v1.ExternalVolumeStatus.VolumeContextEntry + nil, // 162: substrate.ateapi.v1.ExternalVolumeClass.ParametersEntry + nil, // 163: substrate.ateapi.v1.Worker.LabelsEntry + (*timestamppb.Timestamp)(nil), // 164: google.protobuf.Timestamp + (*descriptorpb.MessageOptions)(nil), // 165: google.protobuf.MessageOptions + (*descriptorpb.MethodOptions)(nil), // 166: google.protobuf.MethodOptions } var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 1, // 0: substrate.ateapi.v1.SnapshotStorage.state:type_name -> substrate.ateapi.v1.SnapshotStorageState @@ -11259,12 +11549,12 @@ var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 2, // 3: substrate.ateapi.v1.Snapshot.fidelity:type_name -> substrate.ateapi.v1.SnapshotFidelity 11, // 4: substrate.ateapi.v1.Snapshot.durable_snapshot:type_name -> substrate.ateapi.v1.SnapshotStorage 122, // 5: substrate.ateapi.v1.Snapshot.sandbox_runtime:type_name -> substrate.ateapi.v1.ActorSandboxRuntime - 156, // 6: substrate.ateapi.v1.Selector.match_labels:type_name -> substrate.ateapi.v1.Selector.MatchLabelsEntry - 160, // 7: substrate.ateapi.v1.ResourceMetadata.create_time:type_name -> google.protobuf.Timestamp - 160, // 8: substrate.ateapi.v1.ResourceMetadata.update_time:type_name -> google.protobuf.Timestamp - 160, // 9: substrate.ateapi.v1.ResourceMetadata.delete_time:type_name -> google.protobuf.Timestamp + 160, // 6: substrate.ateapi.v1.Selector.match_labels:type_name -> substrate.ateapi.v1.Selector.MatchLabelsEntry + 164, // 7: substrate.ateapi.v1.ResourceMetadata.create_time:type_name -> google.protobuf.Timestamp + 164, // 8: substrate.ateapi.v1.ResourceMetadata.update_time:type_name -> google.protobuf.Timestamp + 164, // 9: substrate.ateapi.v1.ResourceMetadata.delete_time:type_name -> google.protobuf.Timestamp 16, // 10: substrate.ateapi.v1.ExternalVolumes.volumes:type_name -> substrate.ateapi.v1.ExternalVolumeStatus - 157, // 11: substrate.ateapi.v1.ExternalVolumeStatus.volume_context:type_name -> substrate.ateapi.v1.ExternalVolumeStatus.VolumeContextEntry + 161, // 11: substrate.ateapi.v1.ExternalVolumeStatus.volume_context:type_name -> substrate.ateapi.v1.ExternalVolumeStatus.VolumeContextEntry 14, // 12: substrate.ateapi.v1.Actor.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata 35, // 13: substrate.ateapi.v1.Actor.actor_template:type_name -> substrate.ateapi.v1.ObjectRef 13, // 14: substrate.ateapi.v1.Actor.worker_selector:type_name -> substrate.ateapi.v1.Selector @@ -11289,7 +11579,7 @@ var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 15, // 33: substrate.ateapi.v1.ActorStatus.external_volumes:type_name -> substrate.ateapi.v1.ExternalVolumes 30, // 34: substrate.ateapi.v1.ActorStatus.crash:type_name -> substrate.ateapi.v1.ActorCrash 12, // 35: substrate.ateapi.v1.ActorStatus.snapshots:type_name -> substrate.ateapi.v1.Snapshot - 160, // 36: substrate.ateapi.v1.ActorCrash.crash_time:type_name -> google.protobuf.Timestamp + 164, // 36: substrate.ateapi.v1.ActorCrash.crash_time:type_name -> google.protobuf.Timestamp 35, // 37: substrate.ateapi.v1.WorkerAssignment.worker:type_name -> substrate.ateapi.v1.ObjectRef 122, // 38: substrate.ateapi.v1.WorkerAssignment.sandbox_runtime:type_name -> substrate.ateapi.v1.ActorSandboxRuntime 12, // 39: substrate.ateapi.v1.TagStatus.snapshot:type_name -> substrate.ateapi.v1.Snapshot @@ -11308,7 +11598,7 @@ var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 40, // 52: substrate.ateapi.v1.ActorTemplate.status:type_name -> substrate.ateapi.v1.ActorTemplateStatus 38, // 53: substrate.ateapi.v1.ResourceRequirements.limits:type_name -> substrate.ateapi.v1.Resources 35, // 54: substrate.ateapi.v1.GoldenSnapshotStatus.golden_tag:type_name -> substrate.ateapi.v1.ObjectRef - 160, // 55: substrate.ateapi.v1.GoldenSnapshotStatus.snapshot_time:type_name -> google.protobuf.Timestamp + 164, // 55: substrate.ateapi.v1.GoldenSnapshotStatus.snapshot_time:type_name -> google.protobuf.Timestamp 39, // 56: substrate.ateapi.v1.ActorTemplateStatus.golden_snapshot_status:type_name -> substrate.ateapi.v1.GoldenSnapshotStatus 2, // 57: substrate.ateapi.v1.SnapshotConfig.preferred_fidelity:type_name -> substrate.ateapi.v1.SnapshotFidelity 42, // 58: substrate.ateapi.v1.SnapshotConfig.golden_snapshot_config:type_name -> substrate.ateapi.v1.GoldenSnapshotConfig @@ -11327,7 +11617,7 @@ var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 53, // 71: substrate.ateapi.v1.ExternalVolumeSource.template:type_name -> substrate.ateapi.v1.ExternalVolumeTemplate 35, // 72: substrate.ateapi.v1.ExternalVolumeTemplate.external_volume_class:type_name -> substrate.ateapi.v1.ObjectRef 14, // 73: substrate.ateapi.v1.ExternalVolumeClass.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata - 158, // 74: substrate.ateapi.v1.ExternalVolumeClass.parameters:type_name -> substrate.ateapi.v1.ExternalVolumeClass.ParametersEntry + 162, // 74: substrate.ateapi.v1.ExternalVolumeClass.parameters:type_name -> substrate.ateapi.v1.ExternalVolumeClass.ParametersEntry 56, // 75: substrate.ateapi.v1.SystemInfoVolumeSource.data_sources:type_name -> substrate.ateapi.v1.SystemInfoDataSource 57, // 76: substrate.ateapi.v1.SystemInfoDataSource.actor_metadata:type_name -> substrate.ateapi.v1.ActorMetadataDataSource 59, // 77: substrate.ateapi.v1.SystemInfoDataSource.trust_bundle:type_name -> substrate.ateapi.v1.TrustBundleDataSource @@ -11373,7 +11663,7 @@ var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 99, // 117: substrate.ateapi.v1.DeleteActorEgressPolicyRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions 35, // 118: substrate.ateapi.v1.GetTagRequest.tag:type_name -> substrate.ateapi.v1.ObjectRef 35, // 119: substrate.ateapi.v1.MintActorJwtRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 160, // 120: substrate.ateapi.v1.MintActorJwtResponse.expire_time:type_name -> google.protobuf.Timestamp + 164, // 120: substrate.ateapi.v1.MintActorJwtResponse.expire_time:type_name -> google.protobuf.Timestamp 100, // 121: substrate.ateapi.v1.ListTagsRequest.options:type_name -> substrate.ateapi.v1.ListOptions 33, // 122: substrate.ateapi.v1.ListTagsResponse.tags:type_name -> substrate.ateapi.v1.Tag 33, // 123: substrate.ateapi.v1.CreateTagRequest.tag:type_name -> substrate.ateapi.v1.Tag @@ -11399,7 +11689,7 @@ var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 100, // 143: substrate.ateapi.v1.ListActorsRequest.options:type_name -> substrate.ateapi.v1.ListOptions 17, // 144: substrate.ateapi.v1.ListActorsResponse.actors:type_name -> substrate.ateapi.v1.Actor 14, // 145: substrate.ateapi.v1.Worker.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata - 159, // 146: substrate.ateapi.v1.Worker.labels:type_name -> substrate.ateapi.v1.Worker.LabelsEntry + 163, // 146: substrate.ateapi.v1.Worker.labels:type_name -> substrate.ateapi.v1.Worker.LabelsEntry 118, // 147: substrate.ateapi.v1.Worker.status:type_name -> substrate.ateapi.v1.WorkerStatus 8, // 148: substrate.ateapi.v1.WorkerStatus.state:type_name -> substrate.ateapi.v1.WorkerState 125, // 149: substrate.ateapi.v1.WorkerStatus.capacity:type_name -> substrate.ateapi.v1.WorkerResources @@ -11424,7 +11714,7 @@ var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 35, // 168: substrate.ateapi.v1.MintWorkerActorCertificateRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef 35, // 169: substrate.ateapi.v1.MintWorkerActorCertificateRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef 35, // 170: substrate.ateapi.v1.MintWorkerActorJwtRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef - 160, // 171: substrate.ateapi.v1.MintWorkerActorJwtResponse.expire_time:type_name -> google.protobuf.Timestamp + 164, // 171: substrate.ateapi.v1.MintWorkerActorJwtResponse.expire_time:type_name -> google.protobuf.Timestamp 35, // 172: substrate.ateapi.v1.RequestActorSuspendRequest.worker:type_name -> substrate.ateapi.v1.ObjectRef 35, // 173: substrate.ateapi.v1.RequestActorSuspendRequest.actor:type_name -> substrate.ateapi.v1.ObjectRef 17, // 174: substrate.ateapi.v1.RequestActorSuspendResponse.actor:type_name -> substrate.ateapi.v1.Actor @@ -11436,11 +11726,11 @@ var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 144, // 180: substrate.ateapi.v1.ActorSnapshotState.latest_local:type_name -> substrate.ateapi.v1.SnapshotReport 144, // 181: substrate.ateapi.v1.ActorSnapshotState.uploading:type_name -> substrate.ateapi.v1.SnapshotReport 144, // 182: substrate.ateapi.v1.ActorSnapshotState.latest_durable:type_name -> substrate.ateapi.v1.SnapshotReport - 160, // 183: substrate.ateapi.v1.ActorSnapshotState.upload_due_time:type_name -> google.protobuf.Timestamp + 164, // 183: substrate.ateapi.v1.ActorSnapshotState.upload_due_time:type_name -> google.protobuf.Timestamp 2, // 184: substrate.ateapi.v1.SnapshotReport.fidelity:type_name -> substrate.ateapi.v1.SnapshotFidelity 10, // 185: substrate.ateapi.v1.SnapshotReport.object:type_name -> substrate.ateapi.v1.ObjectSnapshot - 160, // 186: substrate.ateapi.v1.SnapshotReport.local_commit_time:type_name -> google.protobuf.Timestamp - 160, // 187: substrate.ateapi.v1.SnapshotReport.durable_complete_time:type_name -> google.protobuf.Timestamp + 164, // 186: substrate.ateapi.v1.SnapshotReport.local_commit_time:type_name -> google.protobuf.Timestamp + 164, // 187: substrate.ateapi.v1.SnapshotReport.durable_complete_time:type_name -> google.protobuf.Timestamp 14, // 188: substrate.ateapi.v1.AccessPolicy.metadata:type_name -> substrate.ateapi.v1.ResourceMetadata 146, // 189: substrate.ateapi.v1.AccessPolicy.bindings:type_name -> substrate.ateapi.v1.Binding 145, // 190: substrate.ateapi.v1.CreateGlobalAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy @@ -11452,124 +11742,139 @@ var file_api_ateapi_v1_ateapi_proto_depIdxs = []int32{ 145, // 196: substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy 35, // 197: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest.atespace:type_name -> substrate.ateapi.v1.ObjectRef 99, // 198: substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions - 9, // 199: substrate.ateapi.v1.ResourceAnnotation.scope:type_name -> substrate.ateapi.v1.Scope - 161, // 200: substrate.ateapi.v1.resource:extendee -> google.protobuf.MessageOptions - 162, // 201: substrate.ateapi.v1.method:extendee -> google.protobuf.MethodOptions - 154, // 202: substrate.ateapi.v1.resource:type_name -> substrate.ateapi.v1.ResourceAnnotation - 155, // 203: substrate.ateapi.v1.method:type_name -> substrate.ateapi.v1.MethodAnnotation - 76, // 204: substrate.ateapi.v1.Control.GetActor:input_type -> substrate.ateapi.v1.GetActorRequest - 77, // 205: substrate.ateapi.v1.Control.CreateActor:input_type -> substrate.ateapi.v1.CreateActorRequest - 78, // 206: substrate.ateapi.v1.Control.UpdateActor:input_type -> substrate.ateapi.v1.UpdateActorRequest - 79, // 207: substrate.ateapi.v1.Control.SuspendActor:input_type -> substrate.ateapi.v1.SuspendActorRequest - 82, // 208: substrate.ateapi.v1.Control.ResumeActor:input_type -> substrate.ateapi.v1.ResumeActorRequest - 84, // 209: substrate.ateapi.v1.Control.RevertActor:input_type -> substrate.ateapi.v1.RevertActorRequest - 86, // 210: substrate.ateapi.v1.Control.DeleteActor:input_type -> substrate.ateapi.v1.DeleteActorRequest - 87, // 211: substrate.ateapi.v1.Control.GetActorEgressPolicy:input_type -> substrate.ateapi.v1.GetActorEgressPolicyRequest - 88, // 212: substrate.ateapi.v1.Control.CreateActorEgressPolicy:input_type -> substrate.ateapi.v1.CreateActorEgressPolicyRequest - 89, // 213: substrate.ateapi.v1.Control.UpdateActorEgressPolicy:input_type -> substrate.ateapi.v1.UpdateActorEgressPolicyRequest - 90, // 214: substrate.ateapi.v1.Control.DeleteActorEgressPolicy:input_type -> substrate.ateapi.v1.DeleteActorEgressPolicyRequest - 92, // 215: substrate.ateapi.v1.Control.MintActorJwt:input_type -> substrate.ateapi.v1.MintActorJwtRequest - 96, // 216: substrate.ateapi.v1.Control.CreateTag:input_type -> substrate.ateapi.v1.CreateTagRequest - 91, // 217: substrate.ateapi.v1.Control.GetTag:input_type -> substrate.ateapi.v1.GetTagRequest - 94, // 218: substrate.ateapi.v1.Control.ListTags:input_type -> substrate.ateapi.v1.ListTagsRequest - 97, // 219: substrate.ateapi.v1.Control.UpdateTag:input_type -> substrate.ateapi.v1.UpdateTagRequest - 98, // 220: substrate.ateapi.v1.Control.DeleteTag:input_type -> substrate.ateapi.v1.DeleteTagRequest - 103, // 221: substrate.ateapi.v1.Control.ListWorkers:input_type -> substrate.ateapi.v1.ListWorkersRequest - 105, // 222: substrate.ateapi.v1.Control.GetWorker:input_type -> substrate.ateapi.v1.GetWorkerRequest - 106, // 223: substrate.ateapi.v1.Control.CreateWorker:input_type -> substrate.ateapi.v1.CreateWorkerRequest - 107, // 224: substrate.ateapi.v1.Control.UpdateWorker:input_type -> substrate.ateapi.v1.UpdateWorkerRequest - 108, // 225: substrate.ateapi.v1.Control.DeleteWorker:input_type -> substrate.ateapi.v1.DeleteWorkerRequest - 109, // 226: substrate.ateapi.v1.Control.DrainWorker:input_type -> substrate.ateapi.v1.DrainWorkerRequest - 111, // 227: substrate.ateapi.v1.Control.MarkWorkerAvailable:input_type -> substrate.ateapi.v1.MarkWorkerAvailableRequest - 113, // 228: substrate.ateapi.v1.Control.MarkWorkerUnavailable:input_type -> substrate.ateapi.v1.MarkWorkerUnavailableRequest - 101, // 229: substrate.ateapi.v1.Control.ListWorkerActorAssignments:input_type -> substrate.ateapi.v1.ListWorkerActorAssignmentsRequest - 115, // 230: substrate.ateapi.v1.Control.ListActors:input_type -> substrate.ateapi.v1.ListActorsRequest - 61, // 231: substrate.ateapi.v1.Control.CreateAtespace:input_type -> substrate.ateapi.v1.CreateAtespaceRequest - 62, // 232: substrate.ateapi.v1.Control.GetAtespace:input_type -> substrate.ateapi.v1.GetAtespaceRequest - 63, // 233: substrate.ateapi.v1.Control.ListAtespaces:input_type -> substrate.ateapi.v1.ListAtespacesRequest - 65, // 234: substrate.ateapi.v1.Control.DeleteAtespace:input_type -> substrate.ateapi.v1.DeleteAtespaceRequest - 66, // 235: substrate.ateapi.v1.Control.CreateExternalVolumeClass:input_type -> substrate.ateapi.v1.CreateExternalVolumeClassRequest - 67, // 236: substrate.ateapi.v1.Control.GetExternalVolumeClass:input_type -> substrate.ateapi.v1.GetExternalVolumeClassRequest - 68, // 237: substrate.ateapi.v1.Control.ListExternalVolumeClasses:input_type -> substrate.ateapi.v1.ListExternalVolumeClassesRequest - 70, // 238: substrate.ateapi.v1.Control.DeleteExternalVolumeClass:input_type -> substrate.ateapi.v1.DeleteExternalVolumeClassRequest - 71, // 239: substrate.ateapi.v1.Control.CreateActorTemplate:input_type -> substrate.ateapi.v1.CreateActorTemplateRequest - 72, // 240: substrate.ateapi.v1.Control.GetActorTemplate:input_type -> substrate.ateapi.v1.GetActorTemplateRequest - 73, // 241: substrate.ateapi.v1.Control.ListActorTemplates:input_type -> substrate.ateapi.v1.ListActorTemplatesRequest - 75, // 242: substrate.ateapi.v1.Control.DeleteActorTemplate:input_type -> substrate.ateapi.v1.DeleteActorTemplateRequest - 147, // 243: substrate.ateapi.v1.Control.GetGlobalAccessPolicy:input_type -> substrate.ateapi.v1.GetGlobalAccessPolicyRequest - 148, // 244: substrate.ateapi.v1.Control.CreateGlobalAccessPolicy:input_type -> substrate.ateapi.v1.CreateGlobalAccessPolicyRequest - 149, // 245: substrate.ateapi.v1.Control.UpdateGlobalAccessPolicy:input_type -> substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest - 150, // 246: substrate.ateapi.v1.Control.GetAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.GetAtespaceAccessPolicyRequest - 151, // 247: substrate.ateapi.v1.Control.CreateAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest - 152, // 248: substrate.ateapi.v1.Control.UpdateAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest - 153, // 249: substrate.ateapi.v1.Control.DeleteAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest - 127, // 250: substrate.ateapi.v1.WorkerService.AcquireWorkerEpoch:input_type -> substrate.ateapi.v1.AcquireWorkerEpochRequest - 129, // 251: substrate.ateapi.v1.WorkerService.RegisterWorker:input_type -> substrate.ateapi.v1.RegisterWorkerRequest - 131, // 252: substrate.ateapi.v1.WorkerService.SetWorkerSandboxRuntimes:input_type -> substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest - 133, // 253: substrate.ateapi.v1.WorkerService.MintWorkerActorCertificate:input_type -> substrate.ateapi.v1.MintWorkerActorCertificateRequest - 135, // 254: substrate.ateapi.v1.WorkerService.MintWorkerActorJwt:input_type -> substrate.ateapi.v1.MintWorkerActorJwtRequest - 137, // 255: substrate.ateapi.v1.WorkerService.RequestActorSuspend:input_type -> substrate.ateapi.v1.RequestActorSuspendRequest - 141, // 256: substrate.ateapi.v1.WorkerService.ReportActorSnapshotState:input_type -> substrate.ateapi.v1.ReportActorSnapshotStateRequest - 139, // 257: substrate.ateapi.v1.WorkerService.ReportActorCrashed:input_type -> substrate.ateapi.v1.ReportActorCrashedRequest - 17, // 258: substrate.ateapi.v1.Control.GetActor:output_type -> substrate.ateapi.v1.Actor - 17, // 259: substrate.ateapi.v1.Control.CreateActor:output_type -> substrate.ateapi.v1.Actor - 17, // 260: substrate.ateapi.v1.Control.UpdateActor:output_type -> substrate.ateapi.v1.Actor - 80, // 261: substrate.ateapi.v1.Control.SuspendActor:output_type -> substrate.ateapi.v1.SuspendActorResponse - 83, // 262: substrate.ateapi.v1.Control.ResumeActor:output_type -> substrate.ateapi.v1.ResumeActorResponse - 85, // 263: substrate.ateapi.v1.Control.RevertActor:output_type -> substrate.ateapi.v1.RevertActorResponse - 17, // 264: substrate.ateapi.v1.Control.DeleteActor:output_type -> substrate.ateapi.v1.Actor - 18, // 265: substrate.ateapi.v1.Control.GetActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy - 18, // 266: substrate.ateapi.v1.Control.CreateActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy - 18, // 267: substrate.ateapi.v1.Control.UpdateActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy - 18, // 268: substrate.ateapi.v1.Control.DeleteActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy - 93, // 269: substrate.ateapi.v1.Control.MintActorJwt:output_type -> substrate.ateapi.v1.MintActorJwtResponse - 33, // 270: substrate.ateapi.v1.Control.CreateTag:output_type -> substrate.ateapi.v1.Tag - 33, // 271: substrate.ateapi.v1.Control.GetTag:output_type -> substrate.ateapi.v1.Tag - 95, // 272: substrate.ateapi.v1.Control.ListTags:output_type -> substrate.ateapi.v1.ListTagsResponse - 33, // 273: substrate.ateapi.v1.Control.UpdateTag:output_type -> substrate.ateapi.v1.Tag - 33, // 274: substrate.ateapi.v1.Control.DeleteTag:output_type -> substrate.ateapi.v1.Tag - 104, // 275: substrate.ateapi.v1.Control.ListWorkers:output_type -> substrate.ateapi.v1.ListWorkersResponse - 117, // 276: substrate.ateapi.v1.Control.GetWorker:output_type -> substrate.ateapi.v1.Worker - 117, // 277: substrate.ateapi.v1.Control.CreateWorker:output_type -> substrate.ateapi.v1.Worker - 117, // 278: substrate.ateapi.v1.Control.UpdateWorker:output_type -> substrate.ateapi.v1.Worker - 117, // 279: substrate.ateapi.v1.Control.DeleteWorker:output_type -> substrate.ateapi.v1.Worker - 110, // 280: substrate.ateapi.v1.Control.DrainWorker:output_type -> substrate.ateapi.v1.DrainWorkerResponse - 112, // 281: substrate.ateapi.v1.Control.MarkWorkerAvailable:output_type -> substrate.ateapi.v1.MarkWorkerAvailableResponse - 114, // 282: substrate.ateapi.v1.Control.MarkWorkerUnavailable:output_type -> substrate.ateapi.v1.MarkWorkerUnavailableResponse - 102, // 283: substrate.ateapi.v1.Control.ListWorkerActorAssignments:output_type -> substrate.ateapi.v1.ListWorkerActorAssignmentsResponse - 116, // 284: substrate.ateapi.v1.Control.ListActors:output_type -> substrate.ateapi.v1.ListActorsResponse - 34, // 285: substrate.ateapi.v1.Control.CreateAtespace:output_type -> substrate.ateapi.v1.Atespace - 34, // 286: substrate.ateapi.v1.Control.GetAtespace:output_type -> substrate.ateapi.v1.Atespace - 64, // 287: substrate.ateapi.v1.Control.ListAtespaces:output_type -> substrate.ateapi.v1.ListAtespacesResponse - 34, // 288: substrate.ateapi.v1.Control.DeleteAtespace:output_type -> substrate.ateapi.v1.Atespace - 54, // 289: substrate.ateapi.v1.Control.CreateExternalVolumeClass:output_type -> substrate.ateapi.v1.ExternalVolumeClass - 54, // 290: substrate.ateapi.v1.Control.GetExternalVolumeClass:output_type -> substrate.ateapi.v1.ExternalVolumeClass - 69, // 291: substrate.ateapi.v1.Control.ListExternalVolumeClasses:output_type -> substrate.ateapi.v1.ListExternalVolumeClassesResponse - 54, // 292: substrate.ateapi.v1.Control.DeleteExternalVolumeClass:output_type -> substrate.ateapi.v1.ExternalVolumeClass - 36, // 293: substrate.ateapi.v1.Control.CreateActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate - 36, // 294: substrate.ateapi.v1.Control.GetActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate - 74, // 295: substrate.ateapi.v1.Control.ListActorTemplates:output_type -> substrate.ateapi.v1.ListActorTemplatesResponse - 36, // 296: substrate.ateapi.v1.Control.DeleteActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate - 145, // 297: substrate.ateapi.v1.Control.GetGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 145, // 298: substrate.ateapi.v1.Control.CreateGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 145, // 299: substrate.ateapi.v1.Control.UpdateGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 145, // 300: substrate.ateapi.v1.Control.GetAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 145, // 301: substrate.ateapi.v1.Control.CreateAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 145, // 302: substrate.ateapi.v1.Control.UpdateAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 145, // 303: substrate.ateapi.v1.Control.DeleteAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy - 128, // 304: substrate.ateapi.v1.WorkerService.AcquireWorkerEpoch:output_type -> substrate.ateapi.v1.AcquireWorkerEpochResponse - 130, // 305: substrate.ateapi.v1.WorkerService.RegisterWorker:output_type -> substrate.ateapi.v1.RegisterWorkerResponse - 132, // 306: substrate.ateapi.v1.WorkerService.SetWorkerSandboxRuntimes:output_type -> substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse - 134, // 307: substrate.ateapi.v1.WorkerService.MintWorkerActorCertificate:output_type -> substrate.ateapi.v1.MintWorkerActorCertificateResponse - 136, // 308: substrate.ateapi.v1.WorkerService.MintWorkerActorJwt:output_type -> substrate.ateapi.v1.MintWorkerActorJwtResponse - 138, // 309: substrate.ateapi.v1.WorkerService.RequestActorSuspend:output_type -> substrate.ateapi.v1.RequestActorSuspendResponse - 142, // 310: substrate.ateapi.v1.WorkerService.ReportActorSnapshotState:output_type -> substrate.ateapi.v1.ReportActorSnapshotStateResponse - 140, // 311: substrate.ateapi.v1.WorkerService.ReportActorCrashed:output_type -> substrate.ateapi.v1.ReportActorCrashedResponse - 258, // [258:312] is the sub-list for method output_type - 204, // [204:258] is the sub-list for method input_type - 202, // [202:204] is the sub-list for extension type_name - 200, // [200:202] is the sub-list for extension extendee - 0, // [0:200] is the sub-list for field type_name + 35, // 199: substrate.ateapi.v1.GetExternalVolumeClassAccessPolicyRequest.external_volume_class:type_name -> substrate.ateapi.v1.ObjectRef + 35, // 200: substrate.ateapi.v1.CreateExternalVolumeClassAccessPolicyRequest.external_volume_class:type_name -> substrate.ateapi.v1.ObjectRef + 145, // 201: substrate.ateapi.v1.CreateExternalVolumeClassAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy + 35, // 202: substrate.ateapi.v1.UpdateExternalVolumeClassAccessPolicyRequest.external_volume_class:type_name -> substrate.ateapi.v1.ObjectRef + 145, // 203: substrate.ateapi.v1.UpdateExternalVolumeClassAccessPolicyRequest.access_policy:type_name -> substrate.ateapi.v1.AccessPolicy + 35, // 204: substrate.ateapi.v1.DeleteExternalVolumeClassAccessPolicyRequest.external_volume_class:type_name -> substrate.ateapi.v1.ObjectRef + 99, // 205: substrate.ateapi.v1.DeleteExternalVolumeClassAccessPolicyRequest.options:type_name -> substrate.ateapi.v1.DeleteOptions + 9, // 206: substrate.ateapi.v1.ResourceAnnotation.scope:type_name -> substrate.ateapi.v1.Scope + 165, // 207: substrate.ateapi.v1.resource:extendee -> google.protobuf.MessageOptions + 166, // 208: substrate.ateapi.v1.method:extendee -> google.protobuf.MethodOptions + 158, // 209: substrate.ateapi.v1.resource:type_name -> substrate.ateapi.v1.ResourceAnnotation + 159, // 210: substrate.ateapi.v1.method:type_name -> substrate.ateapi.v1.MethodAnnotation + 76, // 211: substrate.ateapi.v1.Control.GetActor:input_type -> substrate.ateapi.v1.GetActorRequest + 77, // 212: substrate.ateapi.v1.Control.CreateActor:input_type -> substrate.ateapi.v1.CreateActorRequest + 78, // 213: substrate.ateapi.v1.Control.UpdateActor:input_type -> substrate.ateapi.v1.UpdateActorRequest + 79, // 214: substrate.ateapi.v1.Control.SuspendActor:input_type -> substrate.ateapi.v1.SuspendActorRequest + 82, // 215: substrate.ateapi.v1.Control.ResumeActor:input_type -> substrate.ateapi.v1.ResumeActorRequest + 84, // 216: substrate.ateapi.v1.Control.RevertActor:input_type -> substrate.ateapi.v1.RevertActorRequest + 86, // 217: substrate.ateapi.v1.Control.DeleteActor:input_type -> substrate.ateapi.v1.DeleteActorRequest + 87, // 218: substrate.ateapi.v1.Control.GetActorEgressPolicy:input_type -> substrate.ateapi.v1.GetActorEgressPolicyRequest + 88, // 219: substrate.ateapi.v1.Control.CreateActorEgressPolicy:input_type -> substrate.ateapi.v1.CreateActorEgressPolicyRequest + 89, // 220: substrate.ateapi.v1.Control.UpdateActorEgressPolicy:input_type -> substrate.ateapi.v1.UpdateActorEgressPolicyRequest + 90, // 221: substrate.ateapi.v1.Control.DeleteActorEgressPolicy:input_type -> substrate.ateapi.v1.DeleteActorEgressPolicyRequest + 92, // 222: substrate.ateapi.v1.Control.MintActorJwt:input_type -> substrate.ateapi.v1.MintActorJwtRequest + 96, // 223: substrate.ateapi.v1.Control.CreateTag:input_type -> substrate.ateapi.v1.CreateTagRequest + 91, // 224: substrate.ateapi.v1.Control.GetTag:input_type -> substrate.ateapi.v1.GetTagRequest + 94, // 225: substrate.ateapi.v1.Control.ListTags:input_type -> substrate.ateapi.v1.ListTagsRequest + 97, // 226: substrate.ateapi.v1.Control.UpdateTag:input_type -> substrate.ateapi.v1.UpdateTagRequest + 98, // 227: substrate.ateapi.v1.Control.DeleteTag:input_type -> substrate.ateapi.v1.DeleteTagRequest + 103, // 228: substrate.ateapi.v1.Control.ListWorkers:input_type -> substrate.ateapi.v1.ListWorkersRequest + 105, // 229: substrate.ateapi.v1.Control.GetWorker:input_type -> substrate.ateapi.v1.GetWorkerRequest + 106, // 230: substrate.ateapi.v1.Control.CreateWorker:input_type -> substrate.ateapi.v1.CreateWorkerRequest + 107, // 231: substrate.ateapi.v1.Control.UpdateWorker:input_type -> substrate.ateapi.v1.UpdateWorkerRequest + 108, // 232: substrate.ateapi.v1.Control.DeleteWorker:input_type -> substrate.ateapi.v1.DeleteWorkerRequest + 109, // 233: substrate.ateapi.v1.Control.DrainWorker:input_type -> substrate.ateapi.v1.DrainWorkerRequest + 111, // 234: substrate.ateapi.v1.Control.MarkWorkerAvailable:input_type -> substrate.ateapi.v1.MarkWorkerAvailableRequest + 113, // 235: substrate.ateapi.v1.Control.MarkWorkerUnavailable:input_type -> substrate.ateapi.v1.MarkWorkerUnavailableRequest + 101, // 236: substrate.ateapi.v1.Control.ListWorkerActorAssignments:input_type -> substrate.ateapi.v1.ListWorkerActorAssignmentsRequest + 115, // 237: substrate.ateapi.v1.Control.ListActors:input_type -> substrate.ateapi.v1.ListActorsRequest + 61, // 238: substrate.ateapi.v1.Control.CreateAtespace:input_type -> substrate.ateapi.v1.CreateAtespaceRequest + 62, // 239: substrate.ateapi.v1.Control.GetAtespace:input_type -> substrate.ateapi.v1.GetAtespaceRequest + 63, // 240: substrate.ateapi.v1.Control.ListAtespaces:input_type -> substrate.ateapi.v1.ListAtespacesRequest + 65, // 241: substrate.ateapi.v1.Control.DeleteAtespace:input_type -> substrate.ateapi.v1.DeleteAtespaceRequest + 66, // 242: substrate.ateapi.v1.Control.CreateExternalVolumeClass:input_type -> substrate.ateapi.v1.CreateExternalVolumeClassRequest + 67, // 243: substrate.ateapi.v1.Control.GetExternalVolumeClass:input_type -> substrate.ateapi.v1.GetExternalVolumeClassRequest + 68, // 244: substrate.ateapi.v1.Control.ListExternalVolumeClasses:input_type -> substrate.ateapi.v1.ListExternalVolumeClassesRequest + 70, // 245: substrate.ateapi.v1.Control.DeleteExternalVolumeClass:input_type -> substrate.ateapi.v1.DeleteExternalVolumeClassRequest + 71, // 246: substrate.ateapi.v1.Control.CreateActorTemplate:input_type -> substrate.ateapi.v1.CreateActorTemplateRequest + 72, // 247: substrate.ateapi.v1.Control.GetActorTemplate:input_type -> substrate.ateapi.v1.GetActorTemplateRequest + 73, // 248: substrate.ateapi.v1.Control.ListActorTemplates:input_type -> substrate.ateapi.v1.ListActorTemplatesRequest + 75, // 249: substrate.ateapi.v1.Control.DeleteActorTemplate:input_type -> substrate.ateapi.v1.DeleteActorTemplateRequest + 147, // 250: substrate.ateapi.v1.Control.GetGlobalAccessPolicy:input_type -> substrate.ateapi.v1.GetGlobalAccessPolicyRequest + 148, // 251: substrate.ateapi.v1.Control.CreateGlobalAccessPolicy:input_type -> substrate.ateapi.v1.CreateGlobalAccessPolicyRequest + 149, // 252: substrate.ateapi.v1.Control.UpdateGlobalAccessPolicy:input_type -> substrate.ateapi.v1.UpdateGlobalAccessPolicyRequest + 150, // 253: substrate.ateapi.v1.Control.GetAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.GetAtespaceAccessPolicyRequest + 151, // 254: substrate.ateapi.v1.Control.CreateAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.CreateAtespaceAccessPolicyRequest + 152, // 255: substrate.ateapi.v1.Control.UpdateAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.UpdateAtespaceAccessPolicyRequest + 153, // 256: substrate.ateapi.v1.Control.DeleteAtespaceAccessPolicy:input_type -> substrate.ateapi.v1.DeleteAtespaceAccessPolicyRequest + 154, // 257: substrate.ateapi.v1.Control.GetExternalVolumeClassAccessPolicy:input_type -> substrate.ateapi.v1.GetExternalVolumeClassAccessPolicyRequest + 155, // 258: substrate.ateapi.v1.Control.CreateExternalVolumeClassAccessPolicy:input_type -> substrate.ateapi.v1.CreateExternalVolumeClassAccessPolicyRequest + 156, // 259: substrate.ateapi.v1.Control.UpdateExternalVolumeClassAccessPolicy:input_type -> substrate.ateapi.v1.UpdateExternalVolumeClassAccessPolicyRequest + 157, // 260: substrate.ateapi.v1.Control.DeleteExternalVolumeClassAccessPolicy:input_type -> substrate.ateapi.v1.DeleteExternalVolumeClassAccessPolicyRequest + 127, // 261: substrate.ateapi.v1.WorkerService.AcquireWorkerEpoch:input_type -> substrate.ateapi.v1.AcquireWorkerEpochRequest + 129, // 262: substrate.ateapi.v1.WorkerService.RegisterWorker:input_type -> substrate.ateapi.v1.RegisterWorkerRequest + 131, // 263: substrate.ateapi.v1.WorkerService.SetWorkerSandboxRuntimes:input_type -> substrate.ateapi.v1.SetWorkerSandboxRuntimesRequest + 133, // 264: substrate.ateapi.v1.WorkerService.MintWorkerActorCertificate:input_type -> substrate.ateapi.v1.MintWorkerActorCertificateRequest + 135, // 265: substrate.ateapi.v1.WorkerService.MintWorkerActorJwt:input_type -> substrate.ateapi.v1.MintWorkerActorJwtRequest + 137, // 266: substrate.ateapi.v1.WorkerService.RequestActorSuspend:input_type -> substrate.ateapi.v1.RequestActorSuspendRequest + 141, // 267: substrate.ateapi.v1.WorkerService.ReportActorSnapshotState:input_type -> substrate.ateapi.v1.ReportActorSnapshotStateRequest + 139, // 268: substrate.ateapi.v1.WorkerService.ReportActorCrashed:input_type -> substrate.ateapi.v1.ReportActorCrashedRequest + 17, // 269: substrate.ateapi.v1.Control.GetActor:output_type -> substrate.ateapi.v1.Actor + 17, // 270: substrate.ateapi.v1.Control.CreateActor:output_type -> substrate.ateapi.v1.Actor + 17, // 271: substrate.ateapi.v1.Control.UpdateActor:output_type -> substrate.ateapi.v1.Actor + 80, // 272: substrate.ateapi.v1.Control.SuspendActor:output_type -> substrate.ateapi.v1.SuspendActorResponse + 83, // 273: substrate.ateapi.v1.Control.ResumeActor:output_type -> substrate.ateapi.v1.ResumeActorResponse + 85, // 274: substrate.ateapi.v1.Control.RevertActor:output_type -> substrate.ateapi.v1.RevertActorResponse + 17, // 275: substrate.ateapi.v1.Control.DeleteActor:output_type -> substrate.ateapi.v1.Actor + 18, // 276: substrate.ateapi.v1.Control.GetActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy + 18, // 277: substrate.ateapi.v1.Control.CreateActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy + 18, // 278: substrate.ateapi.v1.Control.UpdateActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy + 18, // 279: substrate.ateapi.v1.Control.DeleteActorEgressPolicy:output_type -> substrate.ateapi.v1.EgressPolicy + 93, // 280: substrate.ateapi.v1.Control.MintActorJwt:output_type -> substrate.ateapi.v1.MintActorJwtResponse + 33, // 281: substrate.ateapi.v1.Control.CreateTag:output_type -> substrate.ateapi.v1.Tag + 33, // 282: substrate.ateapi.v1.Control.GetTag:output_type -> substrate.ateapi.v1.Tag + 95, // 283: substrate.ateapi.v1.Control.ListTags:output_type -> substrate.ateapi.v1.ListTagsResponse + 33, // 284: substrate.ateapi.v1.Control.UpdateTag:output_type -> substrate.ateapi.v1.Tag + 33, // 285: substrate.ateapi.v1.Control.DeleteTag:output_type -> substrate.ateapi.v1.Tag + 104, // 286: substrate.ateapi.v1.Control.ListWorkers:output_type -> substrate.ateapi.v1.ListWorkersResponse + 117, // 287: substrate.ateapi.v1.Control.GetWorker:output_type -> substrate.ateapi.v1.Worker + 117, // 288: substrate.ateapi.v1.Control.CreateWorker:output_type -> substrate.ateapi.v1.Worker + 117, // 289: substrate.ateapi.v1.Control.UpdateWorker:output_type -> substrate.ateapi.v1.Worker + 117, // 290: substrate.ateapi.v1.Control.DeleteWorker:output_type -> substrate.ateapi.v1.Worker + 110, // 291: substrate.ateapi.v1.Control.DrainWorker:output_type -> substrate.ateapi.v1.DrainWorkerResponse + 112, // 292: substrate.ateapi.v1.Control.MarkWorkerAvailable:output_type -> substrate.ateapi.v1.MarkWorkerAvailableResponse + 114, // 293: substrate.ateapi.v1.Control.MarkWorkerUnavailable:output_type -> substrate.ateapi.v1.MarkWorkerUnavailableResponse + 102, // 294: substrate.ateapi.v1.Control.ListWorkerActorAssignments:output_type -> substrate.ateapi.v1.ListWorkerActorAssignmentsResponse + 116, // 295: substrate.ateapi.v1.Control.ListActors:output_type -> substrate.ateapi.v1.ListActorsResponse + 34, // 296: substrate.ateapi.v1.Control.CreateAtespace:output_type -> substrate.ateapi.v1.Atespace + 34, // 297: substrate.ateapi.v1.Control.GetAtespace:output_type -> substrate.ateapi.v1.Atespace + 64, // 298: substrate.ateapi.v1.Control.ListAtespaces:output_type -> substrate.ateapi.v1.ListAtespacesResponse + 34, // 299: substrate.ateapi.v1.Control.DeleteAtespace:output_type -> substrate.ateapi.v1.Atespace + 54, // 300: substrate.ateapi.v1.Control.CreateExternalVolumeClass:output_type -> substrate.ateapi.v1.ExternalVolumeClass + 54, // 301: substrate.ateapi.v1.Control.GetExternalVolumeClass:output_type -> substrate.ateapi.v1.ExternalVolumeClass + 69, // 302: substrate.ateapi.v1.Control.ListExternalVolumeClasses:output_type -> substrate.ateapi.v1.ListExternalVolumeClassesResponse + 54, // 303: substrate.ateapi.v1.Control.DeleteExternalVolumeClass:output_type -> substrate.ateapi.v1.ExternalVolumeClass + 36, // 304: substrate.ateapi.v1.Control.CreateActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate + 36, // 305: substrate.ateapi.v1.Control.GetActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate + 74, // 306: substrate.ateapi.v1.Control.ListActorTemplates:output_type -> substrate.ateapi.v1.ListActorTemplatesResponse + 36, // 307: substrate.ateapi.v1.Control.DeleteActorTemplate:output_type -> substrate.ateapi.v1.ActorTemplate + 145, // 308: substrate.ateapi.v1.Control.GetGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 145, // 309: substrate.ateapi.v1.Control.CreateGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 145, // 310: substrate.ateapi.v1.Control.UpdateGlobalAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 145, // 311: substrate.ateapi.v1.Control.GetAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 145, // 312: substrate.ateapi.v1.Control.CreateAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 145, // 313: substrate.ateapi.v1.Control.UpdateAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 145, // 314: substrate.ateapi.v1.Control.DeleteAtespaceAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 145, // 315: substrate.ateapi.v1.Control.GetExternalVolumeClassAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 145, // 316: substrate.ateapi.v1.Control.CreateExternalVolumeClassAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 145, // 317: substrate.ateapi.v1.Control.UpdateExternalVolumeClassAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 145, // 318: substrate.ateapi.v1.Control.DeleteExternalVolumeClassAccessPolicy:output_type -> substrate.ateapi.v1.AccessPolicy + 128, // 319: substrate.ateapi.v1.WorkerService.AcquireWorkerEpoch:output_type -> substrate.ateapi.v1.AcquireWorkerEpochResponse + 130, // 320: substrate.ateapi.v1.WorkerService.RegisterWorker:output_type -> substrate.ateapi.v1.RegisterWorkerResponse + 132, // 321: substrate.ateapi.v1.WorkerService.SetWorkerSandboxRuntimes:output_type -> substrate.ateapi.v1.SetWorkerSandboxRuntimesResponse + 134, // 322: substrate.ateapi.v1.WorkerService.MintWorkerActorCertificate:output_type -> substrate.ateapi.v1.MintWorkerActorCertificateResponse + 136, // 323: substrate.ateapi.v1.WorkerService.MintWorkerActorJwt:output_type -> substrate.ateapi.v1.MintWorkerActorJwtResponse + 138, // 324: substrate.ateapi.v1.WorkerService.RequestActorSuspend:output_type -> substrate.ateapi.v1.RequestActorSuspendResponse + 142, // 325: substrate.ateapi.v1.WorkerService.ReportActorSnapshotState:output_type -> substrate.ateapi.v1.ReportActorSnapshotStateResponse + 140, // 326: substrate.ateapi.v1.WorkerService.ReportActorCrashed:output_type -> substrate.ateapi.v1.ReportActorCrashedResponse + 269, // [269:327] is the sub-list for method output_type + 211, // [211:269] is the sub-list for method input_type + 209, // [209:211] is the sub-list for extension type_name + 207, // [207:209] is the sub-list for extension extendee + 0, // [0:207] is the sub-list for field type_name } func init() { file_api_ateapi_v1_ateapi_proto_init() } @@ -11583,7 +11888,7 @@ func file_api_ateapi_v1_ateapi_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_api_ateapi_v1_ateapi_proto_rawDesc), len(file_api_ateapi_v1_ateapi_proto_rawDesc)), NumEnums: 10, - NumMessages: 150, + NumMessages: 154, NumExtensions: 2, NumServices: 2, }, diff --git a/api/ateapi/v1/ateapi.proto b/api/ateapi/v1/ateapi.proto index 4b401ebdf4..455b9a6016 100644 --- a/api/ateapi/v1/ateapi.proto +++ b/api/ateapi/v1/ateapi.proto @@ -282,6 +282,26 @@ service Control { rpc DeleteAtespaceAccessPolicy(DeleteAtespaceAccessPolicyRequest) returns (AccessPolicy) { option (method).resource = "AccessPolicy"; } + + // Get the access policy resource nested under an ExternalVolumeClass. + rpc GetExternalVolumeClassAccessPolicy(GetExternalVolumeClassAccessPolicyRequest) returns (AccessPolicy) { + option (method).resource = "AccessPolicy"; + } + + // Create the access policy resource nested under an ExternalVolumeClass. + rpc CreateExternalVolumeClassAccessPolicy(CreateExternalVolumeClassAccessPolicyRequest) returns (AccessPolicy) { + option (method).resource = "AccessPolicy"; + } + + // Replace the access policy resource nested under an ExternalVolumeClass. + rpc UpdateExternalVolumeClassAccessPolicy(UpdateExternalVolumeClassAccessPolicyRequest) returns (AccessPolicy) { + option (method).resource = "AccessPolicy"; + } + + // Delete the access policy resource nested under an ExternalVolumeClass. + rpc DeleteExternalVolumeClassAccessPolicy(DeleteExternalVolumeClassAccessPolicyRequest) returns (AccessPolicy) { + option (method).resource = "AccessPolicy"; + } } // ObjectSnapshot addresses a snapshot held in object storage. @@ -3216,15 +3236,15 @@ message SnapshotReport { // access policy resource, named "default". message AccessPolicy { option (resource) = { - parents : [ "Global", "Atespace" ] + parents : [ "Global", "Atespace", "ExternalVolumeClass" ] singleton : true plural : "AccessPolicies" }; // Standard resource metadata. Atespace must match the parent resource (empty - // for global-scoped parents like Global and Atespace) and name must be - // "default". Both are caller-specified on create and immutable. UID, version, - // create_time, and update_time are server-managed. + // for global-scoped parents like Global, Atespace, and ExternalVolumeClass) + // and name must be "default". Both are caller-specified on create and + // immutable. UID, version, create_time, and update_time are server-managed. // // +k8s:required // +k8s:customValidation # name must be "default" @@ -3238,19 +3258,22 @@ message AccessPolicy { repeated Binding bindings = 2; } -// Binding associates a list of principals (members) with a single role. +// Binding associates a list of members with a single role. message Binding { // The role name for the parent resource type (e.g., "owner", "editor", - // "viewer"). + // "viewer", "allowed_atespace"). // // +k8s:required // +k8s:maxLength=64 string role = 1; - // Principal identities granted this role. + // Subjects granted this role: `user:` principals on Global ("owner", + // "viewer") and Atespace ("owner", "editor", "viewer") policies, or + // `atespace:` on ExternalVolumeClass ("allowed_atespace") policies. // Examples: // - "user:alice@example.com" // - "user:sa-ci-runner" + // - "atespace:team-a" // // +k8s:required // +k8s:listType=set @@ -3354,6 +3377,77 @@ message DeleteAtespaceAccessPolicyRequest { DeleteOptions options = 3; } +// GetExternalVolumeClassAccessPolicyRequest identifies an ExternalVolumeClass's access policy. +message GetExternalVolumeClassAccessPolicyRequest { + // The parent ExternalVolumeClass of the access policy resource to retrieve. + // + // +k8s:required + // +k8s:beta(since: "0.0")=+k8s:subfield(atespace)=+k8s:forbidden # TODO: get rid of beta prefix + ObjectRef external_volume_class = 1; + + // Name of the singleton access policy. Must be "default". + // + // +k8s:required + // +k8s:format=k8s-short-name + // +k8s:customValidation # must be "default" + string name = 2; +} + +// CreateExternalVolumeClassAccessPolicyRequest creates an access policy for an ExternalVolumeClass. +message CreateExternalVolumeClassAccessPolicyRequest { + // Parent ExternalVolumeClass under which to create the policy resource. + // + // +k8s:required + // +k8s:beta(since: "0.0")=+k8s:subfield(atespace)=+k8s:forbidden # TODO: get rid of beta prefix + ObjectRef external_volume_class = 1; + + // The policy to create. metadata.name must be "default" and + // metadata.atespace must be empty. + // + // +ate:preview=ExternalVolumes + // +k8s:ifDisabled(ExternalVolumes)=+k8s:forbidden + // +k8s:required + AccessPolicy access_policy = 2; +} + +// UpdateExternalVolumeClassAccessPolicyRequest replaces an ExternalVolumeClass's access policy. +message UpdateExternalVolumeClassAccessPolicyRequest { + // Parent ExternalVolumeClass under which to update the policy resource. + // + // +k8s:required + // +k8s:beta(since: "0.0")=+k8s:subfield(atespace)=+k8s:forbidden # TODO: get rid of beta prefix + ObjectRef external_volume_class = 1; + + // Full replacement. Metadata UID and version are required preconditions; + // metadata.name must be "default" and metadata.atespace must be empty. + // + // +ate:preview=ExternalVolumes + // +k8s:ifDisabled(ExternalVolumes)=+k8s:forbidden + // +k8s:required + AccessPolicy access_policy = 2; +} + +// DeleteExternalVolumeClassAccessPolicyRequest identifies an ExternalVolumeClass's access policy. +message DeleteExternalVolumeClassAccessPolicyRequest { + // The parent ExternalVolumeClass of the access policy resource to delete. + // + // +k8s:required + // +k8s:beta(since: "0.0")=+k8s:subfield(atespace)=+k8s:forbidden # TODO: get rid of beta prefix + ObjectRef external_volume_class = 1; + + // Name of the singleton access policy. Must be "default". + // + // +k8s:required + // +k8s:format=k8s-short-name + // +k8s:customValidation # must be "default" + string name = 2; + + // Optional per-delete preconditions. + // + // +k8s:optional + DeleteOptions options = 3; +} + // ResourceAnnotation marks a message as an API resource. See // docs/resource-model.md. message ResourceAnnotation { diff --git a/api/ateapi/v1/ateapi_grpc.pb.go b/api/ateapi/v1/ateapi_grpc.pb.go index 1432abcebf..35466cc7ce 100644 --- a/api/ateapi/v1/ateapi_grpc.pb.go +++ b/api/ateapi/v1/ateapi_grpc.pb.go @@ -33,52 +33,56 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - Control_GetActor_FullMethodName = "/substrate.ateapi.v1.Control/GetActor" - Control_CreateActor_FullMethodName = "/substrate.ateapi.v1.Control/CreateActor" - Control_UpdateActor_FullMethodName = "/substrate.ateapi.v1.Control/UpdateActor" - Control_SuspendActor_FullMethodName = "/substrate.ateapi.v1.Control/SuspendActor" - Control_ResumeActor_FullMethodName = "/substrate.ateapi.v1.Control/ResumeActor" - Control_RevertActor_FullMethodName = "/substrate.ateapi.v1.Control/RevertActor" - Control_DeleteActor_FullMethodName = "/substrate.ateapi.v1.Control/DeleteActor" - Control_GetActorEgressPolicy_FullMethodName = "/substrate.ateapi.v1.Control/GetActorEgressPolicy" - Control_CreateActorEgressPolicy_FullMethodName = "/substrate.ateapi.v1.Control/CreateActorEgressPolicy" - Control_UpdateActorEgressPolicy_FullMethodName = "/substrate.ateapi.v1.Control/UpdateActorEgressPolicy" - Control_DeleteActorEgressPolicy_FullMethodName = "/substrate.ateapi.v1.Control/DeleteActorEgressPolicy" - Control_MintActorJwt_FullMethodName = "/substrate.ateapi.v1.Control/MintActorJwt" - Control_CreateTag_FullMethodName = "/substrate.ateapi.v1.Control/CreateTag" - Control_GetTag_FullMethodName = "/substrate.ateapi.v1.Control/GetTag" - Control_ListTags_FullMethodName = "/substrate.ateapi.v1.Control/ListTags" - Control_UpdateTag_FullMethodName = "/substrate.ateapi.v1.Control/UpdateTag" - Control_DeleteTag_FullMethodName = "/substrate.ateapi.v1.Control/DeleteTag" - Control_ListWorkers_FullMethodName = "/substrate.ateapi.v1.Control/ListWorkers" - Control_GetWorker_FullMethodName = "/substrate.ateapi.v1.Control/GetWorker" - Control_CreateWorker_FullMethodName = "/substrate.ateapi.v1.Control/CreateWorker" - Control_UpdateWorker_FullMethodName = "/substrate.ateapi.v1.Control/UpdateWorker" - Control_DeleteWorker_FullMethodName = "/substrate.ateapi.v1.Control/DeleteWorker" - Control_DrainWorker_FullMethodName = "/substrate.ateapi.v1.Control/DrainWorker" - Control_MarkWorkerAvailable_FullMethodName = "/substrate.ateapi.v1.Control/MarkWorkerAvailable" - Control_MarkWorkerUnavailable_FullMethodName = "/substrate.ateapi.v1.Control/MarkWorkerUnavailable" - Control_ListWorkerActorAssignments_FullMethodName = "/substrate.ateapi.v1.Control/ListWorkerActorAssignments" - Control_ListActors_FullMethodName = "/substrate.ateapi.v1.Control/ListActors" - Control_CreateAtespace_FullMethodName = "/substrate.ateapi.v1.Control/CreateAtespace" - Control_GetAtespace_FullMethodName = "/substrate.ateapi.v1.Control/GetAtespace" - Control_ListAtespaces_FullMethodName = "/substrate.ateapi.v1.Control/ListAtespaces" - Control_DeleteAtespace_FullMethodName = "/substrate.ateapi.v1.Control/DeleteAtespace" - Control_CreateExternalVolumeClass_FullMethodName = "/substrate.ateapi.v1.Control/CreateExternalVolumeClass" - Control_GetExternalVolumeClass_FullMethodName = "/substrate.ateapi.v1.Control/GetExternalVolumeClass" - Control_ListExternalVolumeClasses_FullMethodName = "/substrate.ateapi.v1.Control/ListExternalVolumeClasses" - Control_DeleteExternalVolumeClass_FullMethodName = "/substrate.ateapi.v1.Control/DeleteExternalVolumeClass" - Control_CreateActorTemplate_FullMethodName = "/substrate.ateapi.v1.Control/CreateActorTemplate" - Control_GetActorTemplate_FullMethodName = "/substrate.ateapi.v1.Control/GetActorTemplate" - Control_ListActorTemplates_FullMethodName = "/substrate.ateapi.v1.Control/ListActorTemplates" - Control_DeleteActorTemplate_FullMethodName = "/substrate.ateapi.v1.Control/DeleteActorTemplate" - Control_GetGlobalAccessPolicy_FullMethodName = "/substrate.ateapi.v1.Control/GetGlobalAccessPolicy" - Control_CreateGlobalAccessPolicy_FullMethodName = "/substrate.ateapi.v1.Control/CreateGlobalAccessPolicy" - Control_UpdateGlobalAccessPolicy_FullMethodName = "/substrate.ateapi.v1.Control/UpdateGlobalAccessPolicy" - Control_GetAtespaceAccessPolicy_FullMethodName = "/substrate.ateapi.v1.Control/GetAtespaceAccessPolicy" - Control_CreateAtespaceAccessPolicy_FullMethodName = "/substrate.ateapi.v1.Control/CreateAtespaceAccessPolicy" - Control_UpdateAtespaceAccessPolicy_FullMethodName = "/substrate.ateapi.v1.Control/UpdateAtespaceAccessPolicy" - Control_DeleteAtespaceAccessPolicy_FullMethodName = "/substrate.ateapi.v1.Control/DeleteAtespaceAccessPolicy" + Control_GetActor_FullMethodName = "/substrate.ateapi.v1.Control/GetActor" + Control_CreateActor_FullMethodName = "/substrate.ateapi.v1.Control/CreateActor" + Control_UpdateActor_FullMethodName = "/substrate.ateapi.v1.Control/UpdateActor" + Control_SuspendActor_FullMethodName = "/substrate.ateapi.v1.Control/SuspendActor" + Control_ResumeActor_FullMethodName = "/substrate.ateapi.v1.Control/ResumeActor" + Control_RevertActor_FullMethodName = "/substrate.ateapi.v1.Control/RevertActor" + Control_DeleteActor_FullMethodName = "/substrate.ateapi.v1.Control/DeleteActor" + Control_GetActorEgressPolicy_FullMethodName = "/substrate.ateapi.v1.Control/GetActorEgressPolicy" + Control_CreateActorEgressPolicy_FullMethodName = "/substrate.ateapi.v1.Control/CreateActorEgressPolicy" + Control_UpdateActorEgressPolicy_FullMethodName = "/substrate.ateapi.v1.Control/UpdateActorEgressPolicy" + Control_DeleteActorEgressPolicy_FullMethodName = "/substrate.ateapi.v1.Control/DeleteActorEgressPolicy" + Control_MintActorJwt_FullMethodName = "/substrate.ateapi.v1.Control/MintActorJwt" + Control_CreateTag_FullMethodName = "/substrate.ateapi.v1.Control/CreateTag" + Control_GetTag_FullMethodName = "/substrate.ateapi.v1.Control/GetTag" + Control_ListTags_FullMethodName = "/substrate.ateapi.v1.Control/ListTags" + Control_UpdateTag_FullMethodName = "/substrate.ateapi.v1.Control/UpdateTag" + Control_DeleteTag_FullMethodName = "/substrate.ateapi.v1.Control/DeleteTag" + Control_ListWorkers_FullMethodName = "/substrate.ateapi.v1.Control/ListWorkers" + Control_GetWorker_FullMethodName = "/substrate.ateapi.v1.Control/GetWorker" + Control_CreateWorker_FullMethodName = "/substrate.ateapi.v1.Control/CreateWorker" + Control_UpdateWorker_FullMethodName = "/substrate.ateapi.v1.Control/UpdateWorker" + Control_DeleteWorker_FullMethodName = "/substrate.ateapi.v1.Control/DeleteWorker" + Control_DrainWorker_FullMethodName = "/substrate.ateapi.v1.Control/DrainWorker" + Control_MarkWorkerAvailable_FullMethodName = "/substrate.ateapi.v1.Control/MarkWorkerAvailable" + Control_MarkWorkerUnavailable_FullMethodName = "/substrate.ateapi.v1.Control/MarkWorkerUnavailable" + Control_ListWorkerActorAssignments_FullMethodName = "/substrate.ateapi.v1.Control/ListWorkerActorAssignments" + Control_ListActors_FullMethodName = "/substrate.ateapi.v1.Control/ListActors" + Control_CreateAtespace_FullMethodName = "/substrate.ateapi.v1.Control/CreateAtespace" + Control_GetAtespace_FullMethodName = "/substrate.ateapi.v1.Control/GetAtespace" + Control_ListAtespaces_FullMethodName = "/substrate.ateapi.v1.Control/ListAtespaces" + Control_DeleteAtespace_FullMethodName = "/substrate.ateapi.v1.Control/DeleteAtespace" + Control_CreateExternalVolumeClass_FullMethodName = "/substrate.ateapi.v1.Control/CreateExternalVolumeClass" + Control_GetExternalVolumeClass_FullMethodName = "/substrate.ateapi.v1.Control/GetExternalVolumeClass" + Control_ListExternalVolumeClasses_FullMethodName = "/substrate.ateapi.v1.Control/ListExternalVolumeClasses" + Control_DeleteExternalVolumeClass_FullMethodName = "/substrate.ateapi.v1.Control/DeleteExternalVolumeClass" + Control_CreateActorTemplate_FullMethodName = "/substrate.ateapi.v1.Control/CreateActorTemplate" + Control_GetActorTemplate_FullMethodName = "/substrate.ateapi.v1.Control/GetActorTemplate" + Control_ListActorTemplates_FullMethodName = "/substrate.ateapi.v1.Control/ListActorTemplates" + Control_DeleteActorTemplate_FullMethodName = "/substrate.ateapi.v1.Control/DeleteActorTemplate" + Control_GetGlobalAccessPolicy_FullMethodName = "/substrate.ateapi.v1.Control/GetGlobalAccessPolicy" + Control_CreateGlobalAccessPolicy_FullMethodName = "/substrate.ateapi.v1.Control/CreateGlobalAccessPolicy" + Control_UpdateGlobalAccessPolicy_FullMethodName = "/substrate.ateapi.v1.Control/UpdateGlobalAccessPolicy" + Control_GetAtespaceAccessPolicy_FullMethodName = "/substrate.ateapi.v1.Control/GetAtespaceAccessPolicy" + Control_CreateAtespaceAccessPolicy_FullMethodName = "/substrate.ateapi.v1.Control/CreateAtespaceAccessPolicy" + Control_UpdateAtespaceAccessPolicy_FullMethodName = "/substrate.ateapi.v1.Control/UpdateAtespaceAccessPolicy" + Control_DeleteAtespaceAccessPolicy_FullMethodName = "/substrate.ateapi.v1.Control/DeleteAtespaceAccessPolicy" + Control_GetExternalVolumeClassAccessPolicy_FullMethodName = "/substrate.ateapi.v1.Control/GetExternalVolumeClassAccessPolicy" + Control_CreateExternalVolumeClassAccessPolicy_FullMethodName = "/substrate.ateapi.v1.Control/CreateExternalVolumeClassAccessPolicy" + Control_UpdateExternalVolumeClassAccessPolicy_FullMethodName = "/substrate.ateapi.v1.Control/UpdateExternalVolumeClassAccessPolicy" + Control_DeleteExternalVolumeClassAccessPolicy_FullMethodName = "/substrate.ateapi.v1.Control/DeleteExternalVolumeClassAccessPolicy" ) // ControlClient is the client API for Control service. @@ -209,6 +213,14 @@ type ControlClient interface { UpdateAtespaceAccessPolicy(ctx context.Context, in *UpdateAtespaceAccessPolicyRequest, opts ...grpc.CallOption) (*AccessPolicy, error) // Delete the access policy resource nested under an Atespace. DeleteAtespaceAccessPolicy(ctx context.Context, in *DeleteAtespaceAccessPolicyRequest, opts ...grpc.CallOption) (*AccessPolicy, error) + // Get the access policy resource nested under an ExternalVolumeClass. + GetExternalVolumeClassAccessPolicy(ctx context.Context, in *GetExternalVolumeClassAccessPolicyRequest, opts ...grpc.CallOption) (*AccessPolicy, error) + // Create the access policy resource nested under an ExternalVolumeClass. + CreateExternalVolumeClassAccessPolicy(ctx context.Context, in *CreateExternalVolumeClassAccessPolicyRequest, opts ...grpc.CallOption) (*AccessPolicy, error) + // Replace the access policy resource nested under an ExternalVolumeClass. + UpdateExternalVolumeClassAccessPolicy(ctx context.Context, in *UpdateExternalVolumeClassAccessPolicyRequest, opts ...grpc.CallOption) (*AccessPolicy, error) + // Delete the access policy resource nested under an ExternalVolumeClass. + DeleteExternalVolumeClassAccessPolicy(ctx context.Context, in *DeleteExternalVolumeClassAccessPolicyRequest, opts ...grpc.CallOption) (*AccessPolicy, error) } type controlClient struct { @@ -679,6 +691,46 @@ func (c *controlClient) DeleteAtespaceAccessPolicy(ctx context.Context, in *Dele return out, nil } +func (c *controlClient) GetExternalVolumeClassAccessPolicy(ctx context.Context, in *GetExternalVolumeClassAccessPolicyRequest, opts ...grpc.CallOption) (*AccessPolicy, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(AccessPolicy) + err := c.cc.Invoke(ctx, Control_GetExternalVolumeClassAccessPolicy_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *controlClient) CreateExternalVolumeClassAccessPolicy(ctx context.Context, in *CreateExternalVolumeClassAccessPolicyRequest, opts ...grpc.CallOption) (*AccessPolicy, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(AccessPolicy) + err := c.cc.Invoke(ctx, Control_CreateExternalVolumeClassAccessPolicy_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *controlClient) UpdateExternalVolumeClassAccessPolicy(ctx context.Context, in *UpdateExternalVolumeClassAccessPolicyRequest, opts ...grpc.CallOption) (*AccessPolicy, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(AccessPolicy) + err := c.cc.Invoke(ctx, Control_UpdateExternalVolumeClassAccessPolicy_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *controlClient) DeleteExternalVolumeClassAccessPolicy(ctx context.Context, in *DeleteExternalVolumeClassAccessPolicyRequest, opts ...grpc.CallOption) (*AccessPolicy, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(AccessPolicy) + err := c.cc.Invoke(ctx, Control_DeleteExternalVolumeClassAccessPolicy_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + // ControlServer is the server API for Control service. // All implementations must embed UnimplementedControlServer // for forward compatibility. @@ -807,6 +859,14 @@ type ControlServer interface { UpdateAtespaceAccessPolicy(context.Context, *UpdateAtespaceAccessPolicyRequest) (*AccessPolicy, error) // Delete the access policy resource nested under an Atespace. DeleteAtespaceAccessPolicy(context.Context, *DeleteAtespaceAccessPolicyRequest) (*AccessPolicy, error) + // Get the access policy resource nested under an ExternalVolumeClass. + GetExternalVolumeClassAccessPolicy(context.Context, *GetExternalVolumeClassAccessPolicyRequest) (*AccessPolicy, error) + // Create the access policy resource nested under an ExternalVolumeClass. + CreateExternalVolumeClassAccessPolicy(context.Context, *CreateExternalVolumeClassAccessPolicyRequest) (*AccessPolicy, error) + // Replace the access policy resource nested under an ExternalVolumeClass. + UpdateExternalVolumeClassAccessPolicy(context.Context, *UpdateExternalVolumeClassAccessPolicyRequest) (*AccessPolicy, error) + // Delete the access policy resource nested under an ExternalVolumeClass. + DeleteExternalVolumeClassAccessPolicy(context.Context, *DeleteExternalVolumeClassAccessPolicyRequest) (*AccessPolicy, error) mustEmbedUnimplementedControlServer() } @@ -955,6 +1015,18 @@ func (UnimplementedControlServer) UpdateAtespaceAccessPolicy(context.Context, *U func (UnimplementedControlServer) DeleteAtespaceAccessPolicy(context.Context, *DeleteAtespaceAccessPolicyRequest) (*AccessPolicy, error) { return nil, status.Error(codes.Unimplemented, "method DeleteAtespaceAccessPolicy not implemented") } +func (UnimplementedControlServer) GetExternalVolumeClassAccessPolicy(context.Context, *GetExternalVolumeClassAccessPolicyRequest) (*AccessPolicy, error) { + return nil, status.Error(codes.Unimplemented, "method GetExternalVolumeClassAccessPolicy not implemented") +} +func (UnimplementedControlServer) CreateExternalVolumeClassAccessPolicy(context.Context, *CreateExternalVolumeClassAccessPolicyRequest) (*AccessPolicy, error) { + return nil, status.Error(codes.Unimplemented, "method CreateExternalVolumeClassAccessPolicy not implemented") +} +func (UnimplementedControlServer) UpdateExternalVolumeClassAccessPolicy(context.Context, *UpdateExternalVolumeClassAccessPolicyRequest) (*AccessPolicy, error) { + return nil, status.Error(codes.Unimplemented, "method UpdateExternalVolumeClassAccessPolicy not implemented") +} +func (UnimplementedControlServer) DeleteExternalVolumeClassAccessPolicy(context.Context, *DeleteExternalVolumeClassAccessPolicyRequest) (*AccessPolicy, error) { + return nil, status.Error(codes.Unimplemented, "method DeleteExternalVolumeClassAccessPolicy not implemented") +} func (UnimplementedControlServer) mustEmbedUnimplementedControlServer() {} func (UnimplementedControlServer) testEmbeddedByValue() {} @@ -1804,6 +1876,78 @@ func _Control_DeleteAtespaceAccessPolicy_Handler(srv interface{}, ctx context.Co return interceptor(ctx, in, info, handler) } +func _Control_GetExternalVolumeClassAccessPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetExternalVolumeClassAccessPolicyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ControlServer).GetExternalVolumeClassAccessPolicy(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Control_GetExternalVolumeClassAccessPolicy_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ControlServer).GetExternalVolumeClassAccessPolicy(ctx, req.(*GetExternalVolumeClassAccessPolicyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Control_CreateExternalVolumeClassAccessPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateExternalVolumeClassAccessPolicyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ControlServer).CreateExternalVolumeClassAccessPolicy(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Control_CreateExternalVolumeClassAccessPolicy_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ControlServer).CreateExternalVolumeClassAccessPolicy(ctx, req.(*CreateExternalVolumeClassAccessPolicyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Control_UpdateExternalVolumeClassAccessPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateExternalVolumeClassAccessPolicyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ControlServer).UpdateExternalVolumeClassAccessPolicy(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Control_UpdateExternalVolumeClassAccessPolicy_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ControlServer).UpdateExternalVolumeClassAccessPolicy(ctx, req.(*UpdateExternalVolumeClassAccessPolicyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Control_DeleteExternalVolumeClassAccessPolicy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteExternalVolumeClassAccessPolicyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ControlServer).DeleteExternalVolumeClassAccessPolicy(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Control_DeleteExternalVolumeClassAccessPolicy_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ControlServer).DeleteExternalVolumeClassAccessPolicy(ctx, req.(*DeleteExternalVolumeClassAccessPolicyRequest)) + } + return interceptor(ctx, in, info, handler) +} + // Control_ServiceDesc is the grpc.ServiceDesc for Control service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -1995,6 +2139,22 @@ var Control_ServiceDesc = grpc.ServiceDesc{ MethodName: "DeleteAtespaceAccessPolicy", Handler: _Control_DeleteAtespaceAccessPolicy_Handler, }, + { + MethodName: "GetExternalVolumeClassAccessPolicy", + Handler: _Control_GetExternalVolumeClassAccessPolicy_Handler, + }, + { + MethodName: "CreateExternalVolumeClassAccessPolicy", + Handler: _Control_CreateExternalVolumeClassAccessPolicy_Handler, + }, + { + MethodName: "UpdateExternalVolumeClassAccessPolicy", + Handler: _Control_UpdateExternalVolumeClassAccessPolicy_Handler, + }, + { + MethodName: "DeleteExternalVolumeClassAccessPolicy", + Handler: _Control_DeleteExternalVolumeClassAccessPolicy_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "api/ateapi/v1/ateapi.proto", diff --git a/cmd/ateapi/internal/apivalidation/access_policy.go b/cmd/ateapi/internal/apivalidation/access_policy.go index 386bb7e60f..b654a728a2 100644 --- a/cmd/ateapi/internal/apivalidation/access_policy.go +++ b/cmd/ateapi/internal/apivalidation/access_policy.go @@ -20,6 +20,7 @@ import ( "go.ate.dev/substrate/api/ateapi/v1" "go.ate.dev/substrate/cmd/ateapi/internal/authz" + "go.ate.dev/substrate/internal/preview" "k8s.io/apimachinery/pkg/api/operation" "k8s.io/apimachinery/pkg/util/validation/field" ) @@ -28,8 +29,9 @@ import ( const maxMembersPerPolicy = 1500 var ( - validGlobalRoles = []string{authz.RoleOwner, authz.RoleViewer} - validAtespaceRoles = []string{authz.RoleOwner, authz.RoleEditor, authz.RoleViewer} + validGlobalRoles = []string{authz.RoleOwner, authz.RoleViewer} + validAtespaceRoles = []string{authz.RoleOwner, authz.RoleEditor, authz.RoleViewer} + validExternalVolumeClassRoles = []string{authz.RoleAllowedAtespace} bindingsPath = field.NewPath("access_policy", "bindings") ) @@ -37,7 +39,7 @@ var ( func ValidateCreateGlobalAccessPolicyRequest(ctx context.Context, req *ateapi.CreateGlobalAccessPolicyRequest) field.ErrorList { op := MakeCreateOp(ctx) errs := Validate_CreateGlobalAccessPolicyRequest(ctx, op, nil, req, nil) - return append(errs, validateBindings(bindingsPath, req.GetAccessPolicy(), validGlobalRoles)...) + return append(errs, validateBindings(bindingsPath, req.GetAccessPolicy(), validGlobalRoles, authz.FormatMember)...) } func ValidateGetGlobalAccessPolicyRequest(ctx context.Context, req *ateapi.GetGlobalAccessPolicyRequest) field.ErrorList { @@ -50,7 +52,7 @@ func ValidateUpdateGlobalAccessPolicyRequest(ctx context.Context, req *ateapi.Up // validated against the stored value by ValidateGlobalAccessPolicyUpdate. op := MakeCreateOp(ctx) errs := Validate_UpdateGlobalAccessPolicyRequest(ctx, op, nil, req, nil) - return append(errs, validateBindings(bindingsPath, req.GetAccessPolicy(), validGlobalRoles)...) + return append(errs, validateBindings(bindingsPath, req.GetAccessPolicy(), validGlobalRoles, authz.FormatMember)...) } // ValidateGlobalAccessPolicyUpdate validates an updated global policy against @@ -58,13 +60,13 @@ func ValidateUpdateGlobalAccessPolicyRequest(ctx context.Context, req *ateapi.Up func ValidateGlobalAccessPolicyUpdate(ctx context.Context, fldPath *field.Path, newVal, oldVal *ateapi.AccessPolicy) field.ErrorList { op := MakeUpdateOp(ctx) errs := Validate_AccessPolicy(ctx, op, fldPath, newVal, oldVal) - return append(errs, validateBindings(fldPath.Child("bindings"), newVal, validGlobalRoles)...) + return append(errs, validateBindings(fldPath.Child("bindings"), newVal, validGlobalRoles, authz.FormatMember)...) } func ValidateCreateAtespaceAccessPolicyRequest(ctx context.Context, req *ateapi.CreateAtespaceAccessPolicyRequest) field.ErrorList { op := MakeCreateOp(ctx) errs := Validate_CreateAtespaceAccessPolicyRequest(ctx, op, nil, req, nil) - return append(errs, validateBindings(bindingsPath, req.GetAccessPolicy(), validAtespaceRoles)...) + return append(errs, validateBindings(bindingsPath, req.GetAccessPolicy(), validAtespaceRoles, authz.FormatMember)...) } func ValidateGetAtespaceAccessPolicyRequest(ctx context.Context, req *ateapi.GetAtespaceAccessPolicyRequest) field.ErrorList { @@ -77,7 +79,7 @@ func ValidateUpdateAtespaceAccessPolicyRequest(ctx context.Context, req *ateapi. // validated against the stored value by ValidateAtespaceAccessPolicyUpdate. op := MakeCreateOp(ctx) errs := Validate_UpdateAtespaceAccessPolicyRequest(ctx, op, nil, req, nil) - return append(errs, validateBindings(bindingsPath, req.GetAccessPolicy(), validAtespaceRoles)...) + return append(errs, validateBindings(bindingsPath, req.GetAccessPolicy(), validAtespaceRoles, authz.FormatMember)...) } // ValidateAtespaceAccessPolicyUpdate validates an updated atespace policy @@ -85,7 +87,7 @@ func ValidateUpdateAtespaceAccessPolicyRequest(ctx context.Context, req *ateapi. func ValidateAtespaceAccessPolicyUpdate(ctx context.Context, fldPath *field.Path, newVal, oldVal *ateapi.AccessPolicy) field.ErrorList { op := MakeUpdateOp(ctx) errs := Validate_AccessPolicy(ctx, op, fldPath, newVal, oldVal) - return append(errs, validateBindings(fldPath.Child("bindings"), newVal, validAtespaceRoles)...) + return append(errs, validateBindings(fldPath.Child("bindings"), newVal, validAtespaceRoles, authz.FormatMember)...) } func ValidateDeleteAtespaceAccessPolicyRequest(ctx context.Context, req *ateapi.DeleteAtespaceAccessPolicyRequest) field.ErrorList { @@ -93,6 +95,44 @@ func ValidateDeleteAtespaceAccessPolicyRequest(ctx context.Context, req *ateapi. return Validate_DeleteAtespaceAccessPolicyRequest(ctx, op, nil, req, nil) } +func ValidateCreateExternalVolumeClassAccessPolicyRequest(ctx context.Context, req *ateapi.CreateExternalVolumeClassAccessPolicyRequest) field.ErrorList { + op := MakeCreateOp(ctx) + errs := Validate_CreateExternalVolumeClassAccessPolicyRequest(ctx, op, nil, req, nil) + if enabled, _ := op.HasOption(string(preview.GateExternalVolumes)); enabled { + errs = append(errs, validateBindings(bindingsPath, req.GetAccessPolicy(), validExternalVolumeClassRoles, authz.FormatAtespaceMember)...) + } + return errs +} + +func ValidateGetExternalVolumeClassAccessPolicyRequest(ctx context.Context, req *ateapi.GetExternalVolumeClassAccessPolicyRequest) field.ErrorList { + op := MakeCreateOp(ctx) + return Validate_GetExternalVolumeClassAccessPolicyRequest(ctx, op, nil, req, nil) +} + +func ValidateUpdateExternalVolumeClassAccessPolicyRequest(ctx context.Context, req *ateapi.UpdateExternalVolumeClassAccessPolicyRequest) field.ErrorList { + // Modeled as a create: this validates the request itself. The result is + // validated against the stored value by ValidateExternalVolumeClassAccessPolicyUpdate. + op := MakeCreateOp(ctx) + errs := Validate_UpdateExternalVolumeClassAccessPolicyRequest(ctx, op, nil, req, nil) + if enabled, _ := op.HasOption(string(preview.GateExternalVolumes)); enabled { + errs = append(errs, validateBindings(bindingsPath, req.GetAccessPolicy(), validExternalVolumeClassRoles, authz.FormatAtespaceMember)...) + } + return errs +} + +// ValidateExternalVolumeClassAccessPolicyUpdate validates an updated external +// volume class access policy against the stored one. +func ValidateExternalVolumeClassAccessPolicyUpdate(ctx context.Context, fldPath *field.Path, newVal, oldVal *ateapi.AccessPolicy) field.ErrorList { + op := MakeUpdateOp(ctx) + errs := Validate_AccessPolicy(ctx, op, fldPath, newVal, oldVal) + return append(errs, validateBindings(fldPath.Child("bindings"), newVal, validExternalVolumeClassRoles, authz.FormatAtespaceMember)...) +} + +func ValidateDeleteExternalVolumeClassAccessPolicyRequest(ctx context.Context, req *ateapi.DeleteExternalVolumeClassAccessPolicyRequest) field.ErrorList { + op := MakeCreateOp(ctx) + return Validate_DeleteExternalVolumeClassAccessPolicyRequest(ctx, op, nil, req, nil) +} + // ValidateCustom_AccessPolicy_Metadata requires an access policy to be the // unatespaced singleton named "default". func ValidateCustom_AccessPolicy_Metadata(_ context.Context, _ operation.Operation, root *field.Path, meta, _ *ateapi.ResourceMetadata) field.ErrorList { @@ -115,10 +155,18 @@ func ValidateCustom_DeleteAtespaceAccessPolicyRequest_Name(_ context.Context, _ return validateSingletonName(p, *name) } +func ValidateCustom_GetExternalVolumeClassAccessPolicyRequest_Name(_ context.Context, _ operation.Operation, p *field.Path, name, _ *string) field.ErrorList { + return validateSingletonName(p, *name) +} + +func ValidateCustom_DeleteExternalVolumeClassAccessPolicyRequest_Name(_ context.Context, _ operation.Operation, p *field.Path, name, _ *string) field.ErrorList { + return validateSingletonName(p, *name) +} + // validateBindings checks that each binding names an allowed role at most once, -// that every member is a valid OpenFGA user, and that the policy stays within +// that every member satisfies formatMember, and that the policy stays within // maxMembersPerPolicy. -func validateBindings(fldPath *field.Path, policy *ateapi.AccessPolicy, allowedRoles []string) field.ErrorList { +func validateBindings(fldPath *field.Path, policy *ateapi.AccessPolicy, allowedRoles []string, formatMember func(string) (string, error)) field.ErrorList { if policy == nil { return nil } @@ -142,7 +190,7 @@ func validateBindings(fldPath *field.Path, policy *ateapi.AccessPolicy, allowedR membersPath := bp.Child("members") totalMembers += len(b.GetMembers()) for j, member := range b.GetMembers() { - if _, err := authz.FormatMember(member); err != nil { + if _, err := formatMember(member); err != nil { errs = append(errs, field.Invalid(membersPath.Index(j), member, err.Error())) } } diff --git a/cmd/ateapi/internal/apivalidation/access_policy_test.go b/cmd/ateapi/internal/apivalidation/access_policy_test.go index 47e455c0a9..64f6132ce3 100644 --- a/cmd/ateapi/internal/apivalidation/access_policy_test.go +++ b/cmd/ateapi/internal/apivalidation/access_policy_test.go @@ -422,3 +422,345 @@ func TestValidateDeleteAtespaceAccessPolicyRequest(t *testing.T) { }) } } + +func validExternalVolumeClassAccessPolicy(mutate ...func(*ateapi.AccessPolicy)) *ateapi.AccessPolicy { + p := &ateapi.AccessPolicy{ + Metadata: &ateapi.ResourceMetadata{Name: "default"}, + Bindings: []*ateapi.Binding{ + {Role: authz.RoleAllowedAtespace, Members: []string{"atespace:team-a", "atespace:team-b"}}, + }, + } + for _, m := range mutate { + m(p) + } + return p +} + +func TestValidateCreateExternalVolumeClassAccessPolicyRequest(t *testing.T) { + evcPath := field.NewPath("external_volume_class") + classRef := &ateapi.ObjectRef{Name: "nfs-gold"} + tests := []struct { + name string + req *ateapi.CreateExternalVolumeClassAccessPolicyRequest + want field.ErrorList + wantWithPreview field.ErrorList + }{{ + name: "valid", + req: &ateapi.CreateExternalVolumeClassAccessPolicyRequest{ExternalVolumeClass: classRef, AccessPolicy: validExternalVolumeClassAccessPolicy()}, + want: field.ErrorList{field.Forbidden(accessPolicyPath, "")}, + }, { + name: "valid without bindings", + req: &ateapi.CreateExternalVolumeClassAccessPolicyRequest{ + ExternalVolumeClass: classRef, + AccessPolicy: validExternalVolumeClassAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings = nil }), + }, + want: field.ErrorList{field.Forbidden(accessPolicyPath, "")}, + }, { + name: "missing external_volume_class", + req: &ateapi.CreateExternalVolumeClassAccessPolicyRequest{AccessPolicy: validExternalVolumeClassAccessPolicy()}, + want: field.ErrorList{field.Required(evcPath, ""), field.Forbidden(accessPolicyPath, "")}, + wantWithPreview: field.ErrorList{field.Required(evcPath, "")}, + }, { + name: "external_volume_class atespace forbidden", + req: &ateapi.CreateExternalVolumeClassAccessPolicyRequest{ + ExternalVolumeClass: &ateapi.ObjectRef{Atespace: "team-a", Name: "nfs-gold"}, + AccessPolicy: validExternalVolumeClassAccessPolicy(), + }, + want: field.ErrorList{field.Forbidden(evcPath.Child("atespace"), ""), field.Forbidden(accessPolicyPath, "")}, + wantWithPreview: field.ErrorList{field.Forbidden(evcPath.Child("atespace"), "")}, + }, { + name: "missing external_volume_class name", + req: &ateapi.CreateExternalVolumeClassAccessPolicyRequest{ + ExternalVolumeClass: &ateapi.ObjectRef{}, + AccessPolicy: validExternalVolumeClassAccessPolicy(), + }, + want: field.ErrorList{field.Required(evcPath.Child("name"), ""), field.Forbidden(accessPolicyPath, "")}, + wantWithPreview: field.ErrorList{field.Required(evcPath.Child("name"), "")}, + }, { + name: "invalid external_volume_class name", + req: &ateapi.CreateExternalVolumeClassAccessPolicyRequest{ + ExternalVolumeClass: &ateapi.ObjectRef{Name: "Bad_Name"}, + AccessPolicy: validExternalVolumeClassAccessPolicy(), + }, + want: field.ErrorList{field.Invalid(evcPath.Child("name"), nil, "").WithOrigin("format=k8s-short-name"), field.Forbidden(accessPolicyPath, "")}, + wantWithPreview: field.ErrorList{field.Invalid(evcPath.Child("name"), nil, "").WithOrigin("format=k8s-short-name")}, + }, { + name: "missing access_policy", + req: &ateapi.CreateExternalVolumeClassAccessPolicyRequest{ExternalVolumeClass: classRef}, + want: field.ErrorList{field.Required(accessPolicyPath, "")}, + wantWithPreview: field.ErrorList{field.Required(accessPolicyPath, "")}, + }, { + name: "metadata atespace set", + req: &ateapi.CreateExternalVolumeClassAccessPolicyRequest{ + ExternalVolumeClass: classRef, + AccessPolicy: validExternalVolumeClassAccessPolicy(func(p *ateapi.AccessPolicy) { p.Metadata.Atespace = "team-a" }), + }, + want: field.ErrorList{field.Forbidden(accessPolicyPath, "")}, + wantWithPreview: field.ErrorList{field.Forbidden(accessPolicyPath.Child("metadata", "atespace"), "")}, + }, { + name: "name not default", + req: &ateapi.CreateExternalVolumeClassAccessPolicyRequest{ + ExternalVolumeClass: classRef, + AccessPolicy: validExternalVolumeClassAccessPolicy(func(p *ateapi.AccessPolicy) { p.Metadata.Name = "other" }), + }, + want: field.ErrorList{field.Forbidden(accessPolicyPath, "")}, + wantWithPreview: field.ErrorList{field.Invalid(accessPolicyPath.Child("metadata", "name"), nil, "").WithOrigin("custom=default")}, + }, { + name: "owner role rejected", + req: &ateapi.CreateExternalVolumeClassAccessPolicyRequest{ + ExternalVolumeClass: classRef, + AccessPolicy: validExternalVolumeClassAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings[0].Role = authz.RoleOwner }), + }, + want: field.ErrorList{field.Forbidden(accessPolicyPath, "")}, + wantWithPreview: field.ErrorList{field.NotSupported[string](policyBindings.Index(0).Child("role"), "", nil)}, + }, { + name: "duplicate allowed_atespace role", + req: &ateapi.CreateExternalVolumeClassAccessPolicyRequest{ + ExternalVolumeClass: classRef, + AccessPolicy: validExternalVolumeClassAccessPolicy(func(p *ateapi.AccessPolicy) { + p.Bindings = append(p.Bindings, &ateapi.Binding{Role: authz.RoleAllowedAtespace, Members: []string{"atespace:team-c"}}) + }), + }, + want: field.ErrorList{field.Forbidden(accessPolicyPath, "")}, + wantWithPreview: field.ErrorList{field.Duplicate(policyBindings.Index(1).Child("role"), nil)}, + }, { + name: "user member rejected", + req: &ateapi.CreateExternalVolumeClassAccessPolicyRequest{ + ExternalVolumeClass: classRef, + AccessPolicy: validExternalVolumeClassAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings[0].Members = []string{"user:alice@example.com"} }), + }, + want: field.ErrorList{field.Forbidden(accessPolicyPath, "")}, + wantWithPreview: field.ErrorList{field.Invalid(policyBindings.Index(0).Child("members").Index(0), nil, "")}, + }, { + name: "member without atespace prefix", + req: &ateapi.CreateExternalVolumeClassAccessPolicyRequest{ + ExternalVolumeClass: classRef, + AccessPolicy: validExternalVolumeClassAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings[0].Members = []string{"team-a"} }), + }, + want: field.ErrorList{field.Forbidden(accessPolicyPath, "")}, + wantWithPreview: field.ErrorList{field.Invalid(policyBindings.Index(0).Child("members").Index(0), nil, "")}, + }, { + name: "wildcard member rejected", + req: &ateapi.CreateExternalVolumeClassAccessPolicyRequest{ + ExternalVolumeClass: classRef, + AccessPolicy: validExternalVolumeClassAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings[0].Members = []string{"atespace:*"} }), + }, + want: field.ErrorList{field.Forbidden(accessPolicyPath, "")}, + wantWithPreview: field.ErrorList{field.Invalid(policyBindings.Index(0).Child("members").Index(0), nil, "")}, + }, { + name: "userset member rejected", + req: &ateapi.CreateExternalVolumeClassAccessPolicyRequest{ + ExternalVolumeClass: classRef, + AccessPolicy: validExternalVolumeClassAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings[0].Members = []string{"atespace:team-a#editor"} }), + }, + want: field.ErrorList{field.Forbidden(accessPolicyPath, "")}, + wantWithPreview: field.ErrorList{field.Invalid(policyBindings.Index(0).Child("members").Index(0), nil, "")}, + }, { + name: "invalid DNS-1123 atespace name rejected", + req: &ateapi.CreateExternalVolumeClassAccessPolicyRequest{ + ExternalVolumeClass: classRef, + AccessPolicy: validExternalVolumeClassAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings[0].Members = []string{"atespace:Team-A"} }), + }, + want: field.ErrorList{field.Forbidden(accessPolicyPath, "")}, + wantWithPreview: field.ErrorList{field.Invalid(policyBindings.Index(0).Child("members").Index(0), nil, "")}, + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assertValidate(t, func() field.ErrorList { + return ValidateCreateExternalVolumeClassAccessPolicyRequest(context.Background(), tt.req) + }, tt.want, map[string]field.ErrorList{"ExternalVolumes": tt.wantWithPreview}) + }) + } +} + +func TestValidateGetExternalVolumeClassAccessPolicyRequest(t *testing.T) { + ctx := context.Background() + evcPath := field.NewPath("external_volume_class") + tests := []struct { + name string + req *ateapi.GetExternalVolumeClassAccessPolicyRequest + wantError field.ErrorList + }{{ + name: "valid", + req: &ateapi.GetExternalVolumeClassAccessPolicyRequest{ExternalVolumeClass: &ateapi.ObjectRef{Name: "nfs-gold"}, Name: resources.SingletonName}, + }, { + name: "missing external_volume_class", + req: &ateapi.GetExternalVolumeClassAccessPolicyRequest{Name: resources.SingletonName}, + wantError: field.ErrorList{field.Required(evcPath, "")}, + }, { + name: "external_volume_class atespace forbidden", + req: &ateapi.GetExternalVolumeClassAccessPolicyRequest{ExternalVolumeClass: &ateapi.ObjectRef{Atespace: "team-a", Name: "nfs-gold"}, Name: resources.SingletonName}, + wantError: field.ErrorList{field.Forbidden(evcPath.Child("atespace"), "")}, + }, { + name: "missing external_volume_class name", + req: &ateapi.GetExternalVolumeClassAccessPolicyRequest{ExternalVolumeClass: &ateapi.ObjectRef{}, Name: resources.SingletonName}, + wantError: field.ErrorList{field.Required(evcPath.Child("name"), "")}, + }, { + name: "invalid external_volume_class name", + req: &ateapi.GetExternalVolumeClassAccessPolicyRequest{ExternalVolumeClass: &ateapi.ObjectRef{Name: "Bad_Name"}, Name: resources.SingletonName}, + wantError: field.ErrorList{field.Invalid(evcPath.Child("name"), nil, "").WithOrigin("format=k8s-short-name")}, + }, { + name: "missing name", + req: &ateapi.GetExternalVolumeClassAccessPolicyRequest{ExternalVolumeClass: &ateapi.ObjectRef{Name: "nfs-gold"}}, + wantError: field.ErrorList{field.Required(field.NewPath("name"), "")}, + }, { + name: "wrong name", + req: &ateapi.GetExternalVolumeClassAccessPolicyRequest{ExternalVolumeClass: &ateapi.ObjectRef{Name: "nfs-gold"}, Name: "other"}, + wantError: field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("custom=default")}, + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assertValidateErr(t, ValidateGetExternalVolumeClassAccessPolicyRequest(ctx, tt.req), tt.wantError) + }) + } +} + +func TestValidateUpdateExternalVolumeClassAccessPolicyRequest(t *testing.T) { + evcPath := field.NewPath("external_volume_class") + classRef := &ateapi.ObjectRef{Name: "nfs-gold"} + tests := []struct { + name string + req *ateapi.UpdateExternalVolumeClassAccessPolicyRequest + want field.ErrorList + wantWithPreview field.ErrorList + }{{ + name: "valid", + req: &ateapi.UpdateExternalVolumeClassAccessPolicyRequest{ExternalVolumeClass: classRef, AccessPolicy: validExternalVolumeClassAccessPolicy()}, + want: field.ErrorList{field.Forbidden(accessPolicyPath, "")}, + }, { + name: "missing external_volume_class", + req: &ateapi.UpdateExternalVolumeClassAccessPolicyRequest{AccessPolicy: validExternalVolumeClassAccessPolicy()}, + want: field.ErrorList{field.Required(evcPath, ""), field.Forbidden(accessPolicyPath, "")}, + wantWithPreview: field.ErrorList{field.Required(evcPath, "")}, + }, { + name: "external_volume_class atespace forbidden", + req: &ateapi.UpdateExternalVolumeClassAccessPolicyRequest{ + ExternalVolumeClass: &ateapi.ObjectRef{Atespace: "team-a", Name: "nfs-gold"}, + AccessPolicy: validExternalVolumeClassAccessPolicy(), + }, + want: field.ErrorList{field.Forbidden(evcPath.Child("atespace"), ""), field.Forbidden(accessPolicyPath, "")}, + wantWithPreview: field.ErrorList{field.Forbidden(evcPath.Child("atespace"), "")}, + }, { + name: "missing external_volume_class name", + req: &ateapi.UpdateExternalVolumeClassAccessPolicyRequest{ + ExternalVolumeClass: &ateapi.ObjectRef{}, + AccessPolicy: validExternalVolumeClassAccessPolicy(), + }, + want: field.ErrorList{field.Required(evcPath.Child("name"), ""), field.Forbidden(accessPolicyPath, "")}, + wantWithPreview: field.ErrorList{field.Required(evcPath.Child("name"), "")}, + }, { + name: "invalid external_volume_class name", + req: &ateapi.UpdateExternalVolumeClassAccessPolicyRequest{ + ExternalVolumeClass: &ateapi.ObjectRef{Name: "Bad_Name"}, + AccessPolicy: validExternalVolumeClassAccessPolicy(), + }, + want: field.ErrorList{field.Invalid(evcPath.Child("name"), nil, "").WithOrigin("format=k8s-short-name"), field.Forbidden(accessPolicyPath, "")}, + wantWithPreview: field.ErrorList{field.Invalid(evcPath.Child("name"), nil, "").WithOrigin("format=k8s-short-name")}, + }, { + name: "missing access_policy", + req: &ateapi.UpdateExternalVolumeClassAccessPolicyRequest{ExternalVolumeClass: classRef}, + want: field.ErrorList{field.Required(accessPolicyPath, "")}, + wantWithPreview: field.ErrorList{field.Required(accessPolicyPath, "")}, + }, { + name: "viewer role rejected", + req: &ateapi.UpdateExternalVolumeClassAccessPolicyRequest{ + ExternalVolumeClass: classRef, + AccessPolicy: validExternalVolumeClassAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings[0].Role = authz.RoleViewer }), + }, + want: field.ErrorList{field.Forbidden(accessPolicyPath, "")}, + wantWithPreview: field.ErrorList{field.NotSupported[string](policyBindings.Index(0).Child("role"), "", nil)}, + }, { + name: "user member rejected", + req: &ateapi.UpdateExternalVolumeClassAccessPolicyRequest{ + ExternalVolumeClass: classRef, + AccessPolicy: validExternalVolumeClassAccessPolicy(func(p *ateapi.AccessPolicy) { p.Bindings[0].Members = []string{"user:bob"} }), + }, + want: field.ErrorList{field.Forbidden(accessPolicyPath, "")}, + wantWithPreview: field.ErrorList{field.Invalid(policyBindings.Index(0).Child("members").Index(0), nil, "")}, + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assertValidate(t, func() field.ErrorList { + return ValidateUpdateExternalVolumeClassAccessPolicyRequest(context.Background(), tt.req) + }, tt.want, map[string]field.ErrorList{"ExternalVolumes": tt.wantWithPreview}) + }) + } +} + +func TestValidateExternalVolumeClassAccessPolicyUpdate(t *testing.T) { + ctx := context.Background() + tests := []struct { + name string + newVal *ateapi.AccessPolicy + wantError field.ErrorList + }{{ + name: "valid", + newVal: validExternalVolumeClassAccessPolicy(), + }, { + name: "owner role rejected", + newVal: validExternalVolumeClassAccessPolicy(func(p *ateapi.AccessPolicy) { + p.Bindings[0].Role = authz.RoleOwner + }), + wantError: field.ErrorList{field.NotSupported[string](policyBindings.Index(0).Child("role"), "", nil)}, + }, { + name: "invalid atespace member", + newVal: validExternalVolumeClassAccessPolicy(func(p *ateapi.AccessPolicy) { + p.Bindings[0].Members = []string{"atespace:Bad_Name"} + }), + wantError: field.ErrorList{field.Invalid(policyBindings.Index(0).Child("members").Index(0), nil, "")}, + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assertValidateErr(t, ValidateExternalVolumeClassAccessPolicyUpdate(ctx, accessPolicyPath, tt.newVal, validExternalVolumeClassAccessPolicy()), tt.wantError) + }) + } +} + +func TestValidateDeleteExternalVolumeClassAccessPolicyRequest(t *testing.T) { + ctx := context.Background() + evcPath := field.NewPath("external_volume_class") + tests := []struct { + name string + req *ateapi.DeleteExternalVolumeClassAccessPolicyRequest + wantError field.ErrorList + }{{ + name: "valid", + req: &ateapi.DeleteExternalVolumeClassAccessPolicyRequest{ExternalVolumeClass: &ateapi.ObjectRef{Name: "nfs-gold"}, Name: resources.SingletonName}, + }, { + name: "valid with delete options", + req: &ateapi.DeleteExternalVolumeClassAccessPolicyRequest{ExternalVolumeClass: &ateapi.ObjectRef{Name: "nfs-gold"}, Name: resources.SingletonName, Options: &ateapi.DeleteOptions{Version: 2}}, + }, { + name: "missing external_volume_class", + req: &ateapi.DeleteExternalVolumeClassAccessPolicyRequest{Name: resources.SingletonName}, + wantError: field.ErrorList{field.Required(evcPath, "")}, + }, { + name: "external_volume_class atespace forbidden", + req: &ateapi.DeleteExternalVolumeClassAccessPolicyRequest{ExternalVolumeClass: &ateapi.ObjectRef{Atespace: "team-a", Name: "nfs-gold"}, Name: resources.SingletonName}, + wantError: field.ErrorList{field.Forbidden(evcPath.Child("atespace"), "")}, + }, { + name: "missing external_volume_class name", + req: &ateapi.DeleteExternalVolumeClassAccessPolicyRequest{ExternalVolumeClass: &ateapi.ObjectRef{}, Name: resources.SingletonName}, + wantError: field.ErrorList{field.Required(evcPath.Child("name"), "")}, + }, { + name: "invalid external_volume_class name", + req: &ateapi.DeleteExternalVolumeClassAccessPolicyRequest{ExternalVolumeClass: &ateapi.ObjectRef{Name: "Bad_Name"}, Name: resources.SingletonName}, + wantError: field.ErrorList{field.Invalid(evcPath.Child("name"), nil, "").WithOrigin("format=k8s-short-name")}, + }, { + name: "missing name", + req: &ateapi.DeleteExternalVolumeClassAccessPolicyRequest{ExternalVolumeClass: &ateapi.ObjectRef{Name: "nfs-gold"}}, + wantError: field.ErrorList{field.Required(field.NewPath("name"), "")}, + }, { + name: "wrong name", + req: &ateapi.DeleteExternalVolumeClassAccessPolicyRequest{ExternalVolumeClass: &ateapi.ObjectRef{Name: "nfs-gold"}, Name: "other"}, + wantError: field.ErrorList{field.Invalid(field.NewPath("name"), nil, "").WithOrigin("custom=default")}, + }, { + name: "invalid delete options", + req: &ateapi.DeleteExternalVolumeClassAccessPolicyRequest{ExternalVolumeClass: &ateapi.ObjectRef{Name: "nfs-gold"}, Name: resources.SingletonName, Options: &ateapi.DeleteOptions{Version: -1}}, + wantError: field.ErrorList{field.Invalid(field.NewPath("options", "version"), int64(-1), "").WithOrigin("minimum")}, + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assertValidateErr(t, ValidateDeleteExternalVolumeClassAccessPolicyRequest(ctx, tt.req), tt.wantError) + }) + } +} diff --git a/cmd/ateapi/internal/apivalidation/zz_generated.validation.go b/cmd/ateapi/internal/apivalidation/zz_generated.validation.go index 83e1ca4d21..f02297be24 100644 --- a/cmd/ateapi/internal/apivalidation/zz_generated.validation.go +++ b/cmd/ateapi/internal/apivalidation/zz_generated.validation.go @@ -2449,6 +2449,103 @@ func Validate_CreateAtespaceRequest( return errs } +// Validate_CreateExternalVolumeClassAccessPolicyRequest validates an instance of CreateExternalVolumeClassAccessPolicyRequest according +// to declarative validation rules in the API schema. +func Validate_CreateExternalVolumeClassAccessPolicyRequest( + ctx context.Context, op operation.Operation, fldPath *field.Path, + obj, oldObj *v1.CreateExternalVolumeClassAccessPolicyRequest) (errs field.ErrorList) { + + { // field v1.CreateExternalVolumeClassAccessPolicyRequest.ExternalVolumeClass + fn := func( + fldPath *field.Path, + obj, oldObj *v1.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 *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().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 *v1.CreateExternalVolumeClassAccessPolicyRequest) *v1.ObjectRef { + return oldObj.ExternalVolumeClass + }) + errs = append(errs, fn(fldPath.Child("external_volume_class"), obj.ExternalVolumeClass, oldVal, oldObj != nil)...) + } + + { // field v1.CreateExternalVolumeClassAccessPolicyRequest.AccessPolicy + fn := func( + fldPath *field.Path, + obj, oldObj *v1.AccessPolicy, + 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.IfOption(ctx, op, fldPath, obj, oldObj, "ExternalVolumes", false, validate.ForbiddenPointer).MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "ExternalVolumes", false, validate.OptionalPointer).MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + 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_AccessPolicy(ctx, op, fldPath, obj, oldObj)...) + return + } + oldVal := safe.Field(oldObj, + func(oldObj *v1.CreateExternalVolumeClassAccessPolicyRequest) *v1.AccessPolicy { + return oldObj.AccessPolicy + }) + errs = append(errs, fn(fldPath.Child("access_policy"), obj.AccessPolicy, oldVal, oldObj != nil)...) + } + + return errs +} + // Validate_CreateExternalVolumeClassRequest validates an instance of CreateExternalVolumeClassRequest according // to declarative validation rules in the API schema. func Validate_CreateExternalVolumeClassRequest( @@ -3281,6 +3378,131 @@ func Validate_DeleteAtespaceRequest( return errs } +// Validate_DeleteExternalVolumeClassAccessPolicyRequest validates an instance of DeleteExternalVolumeClassAccessPolicyRequest according +// to declarative validation rules in the API schema. +func Validate_DeleteExternalVolumeClassAccessPolicyRequest( + ctx context.Context, op operation.Operation, fldPath *field.Path, + obj, oldObj *v1.DeleteExternalVolumeClassAccessPolicyRequest) (errs field.ErrorList) { + + { // field v1.DeleteExternalVolumeClassAccessPolicyRequest.ExternalVolumeClass + fn := func( + fldPath *field.Path, + obj, oldObj *v1.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 *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().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 *v1.DeleteExternalVolumeClassAccessPolicyRequest) *v1.ObjectRef { + return oldObj.ExternalVolumeClass + }) + errs = append(errs, fn(fldPath.Child("external_volume_class"), obj.ExternalVolumeClass, oldVal, oldObj != nil)...) + } + + { // field v1.DeleteExternalVolumeClassAccessPolicyRequest.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_DeleteExternalVolumeClassAccessPolicyRequest_Name(ctx, op, fldPath, obj, oldObj); len(e) != 0 { + errs = append(errs, e...) + } + if e := validate.ShortName(ctx, op, fldPath, obj, oldObj); len(e) != 0 { + errs = append(errs, e...) + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *v1.DeleteExternalVolumeClassAccessPolicyRequest) *string { + return &oldObj.Name + }) + errs = append(errs, fn(fldPath.Child("name"), &obj.Name, oldVal, oldObj != nil)...) + } + + { // field v1.DeleteExternalVolumeClassAccessPolicyRequest.Options + fn := func( + fldPath *field.Path, + obj, oldObj *v1.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 *v1.DeleteExternalVolumeClassAccessPolicyRequest) *v1.DeleteOptions { + return oldObj.Options + }) + errs = append(errs, fn(fldPath.Child("options"), obj.Options, oldVal, oldObj != nil)...) + } + + return errs +} + // Validate_DeleteExternalVolumeClassRequest validates an instance of DeleteExternalVolumeClassRequest according // to declarative validation rules in the API schema. func Validate_DeleteExternalVolumeClassRequest( @@ -5008,6 +5230,101 @@ func Validate_GetAtespaceRequest( return errs } +// Validate_GetExternalVolumeClassAccessPolicyRequest validates an instance of GetExternalVolumeClassAccessPolicyRequest according +// to declarative validation rules in the API schema. +func Validate_GetExternalVolumeClassAccessPolicyRequest( + ctx context.Context, op operation.Operation, fldPath *field.Path, + obj, oldObj *v1.GetExternalVolumeClassAccessPolicyRequest) (errs field.ErrorList) { + + { // field v1.GetExternalVolumeClassAccessPolicyRequest.ExternalVolumeClass + fn := func( + fldPath *field.Path, + obj, oldObj *v1.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 *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().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 *v1.GetExternalVolumeClassAccessPolicyRequest) *v1.ObjectRef { + return oldObj.ExternalVolumeClass + }) + errs = append(errs, fn(fldPath.Child("external_volume_class"), obj.ExternalVolumeClass, oldVal, oldObj != nil)...) + } + + { // field v1.GetExternalVolumeClassAccessPolicyRequest.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_GetExternalVolumeClassAccessPolicyRequest_Name(ctx, op, fldPath, obj, oldObj); len(e) != 0 { + errs = append(errs, e...) + } + if e := validate.ShortName(ctx, op, fldPath, obj, oldObj); len(e) != 0 { + errs = append(errs, e...) + } + return + } + oldVal := safe.Field(oldObj, + func(oldObj *v1.GetExternalVolumeClassAccessPolicyRequest) *string { + return &oldObj.Name + }) + errs = append(errs, fn(fldPath.Child("name"), &obj.Name, oldVal, oldObj != nil)...) + } + + return errs +} + // Validate_GetExternalVolumeClassRequest validates an instance of GetExternalVolumeClassRequest according // to declarative validation rules in the API schema. func Validate_GetExternalVolumeClassRequest( @@ -10006,6 +10323,103 @@ func Validate_UpdateAtespaceAccessPolicyRequest( return errs } +// Validate_UpdateExternalVolumeClassAccessPolicyRequest validates an instance of UpdateExternalVolumeClassAccessPolicyRequest according +// to declarative validation rules in the API schema. +func Validate_UpdateExternalVolumeClassAccessPolicyRequest( + ctx context.Context, op operation.Operation, fldPath *field.Path, + obj, oldObj *v1.UpdateExternalVolumeClassAccessPolicyRequest) (errs field.ErrorList) { + + { // field v1.UpdateExternalVolumeClassAccessPolicyRequest.ExternalVolumeClass + fn := func( + fldPath *field.Path, + obj, oldObj *v1.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 *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.ForbiddenValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "atespace", + func(o *v1.ObjectRef) *string { return &o.Atespace }, validate.DirectEqual, validate.OptionalValue).MarkBeta().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 *v1.UpdateExternalVolumeClassAccessPolicyRequest) *v1.ObjectRef { + return oldObj.ExternalVolumeClass + }) + errs = append(errs, fn(fldPath.Child("external_volume_class"), obj.ExternalVolumeClass, oldVal, oldObj != nil)...) + } + + { // field v1.UpdateExternalVolumeClassAccessPolicyRequest.AccessPolicy + fn := func( + fldPath *field.Path, + obj, oldObj *v1.AccessPolicy, + 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.IfOption(ctx, op, fldPath, obj, oldObj, "ExternalVolumes", false, validate.ForbiddenPointer).MarkShortCircuit(); len(e) != 0 { + errs = append(errs, e...) + earlyReturn = true + } + if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "ExternalVolumes", false, validate.OptionalPointer).MarkShortCircuit(); len(e) != 0 { + earlyReturn = true + } + 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_AccessPolicy(ctx, op, fldPath, obj, oldObj)...) + return + } + oldVal := safe.Field(oldObj, + func(oldObj *v1.UpdateExternalVolumeClassAccessPolicyRequest) *v1.AccessPolicy { + return oldObj.AccessPolicy + }) + errs = append(errs, fn(fldPath.Child("access_policy"), obj.AccessPolicy, 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/authz/registry.go b/cmd/ateapi/internal/authz/registry.go index d8f136b428..9a8c207656 100644 --- a/cmd/ateapi/internal/authz/registry.go +++ b/cmd/ateapi/internal/authz/registry.go @@ -314,6 +314,18 @@ var defaultRPCPermissions = map[string]rpcRule{ ateapi.Control_DeleteExternalVolumeClass_FullMethodName: rule(checksOf(func(r *ateapi.DeleteExternalVolumeClassRequest) ([]check, field.ErrorList) { return onExternalVolumeClass(RelationCanDelete, r.GetExternalVolumeClass().GetName(), field.NewPath("external_volume_class", "name")) })), + ateapi.Control_GetExternalVolumeClassAccessPolicy_FullMethodName: rule(checksOf(func(r *ateapi.GetExternalVolumeClassAccessPolicyRequest) ([]check, field.ErrorList) { + return onExternalVolumeClass(RelationCanGetAccessPolicy, r.GetExternalVolumeClass().GetName(), field.NewPath("external_volume_class", "name")) + })), + ateapi.Control_CreateExternalVolumeClassAccessPolicy_FullMethodName: rule(checksOf(func(r *ateapi.CreateExternalVolumeClassAccessPolicyRequest) ([]check, field.ErrorList) { + return onExternalVolumeClass(RelationCanCreateAccessPolicy, r.GetExternalVolumeClass().GetName(), field.NewPath("external_volume_class", "name")) + })), + ateapi.Control_UpdateExternalVolumeClassAccessPolicy_FullMethodName: rule(checksOf(func(r *ateapi.UpdateExternalVolumeClassAccessPolicyRequest) ([]check, field.ErrorList) { + return onExternalVolumeClass(RelationCanUpdateAccessPolicy, r.GetExternalVolumeClass().GetName(), field.NewPath("external_volume_class", "name")) + })), + ateapi.Control_DeleteExternalVolumeClassAccessPolicy_FullMethodName: rule(checksOf(func(r *ateapi.DeleteExternalVolumeClassAccessPolicyRequest) ([]check, field.ErrorList) { + return onExternalVolumeClass(RelationCanDeleteAccessPolicy, r.GetExternalVolumeClass().GetName(), field.NewPath("external_volume_class", "name")) + })), // Actor identity credentials. ateapi.Control_MintActorJwt_FullMethodName: rule(checksOf(func(r *ateapi.MintActorJwtRequest) ([]check, field.ErrorList) { diff --git a/cmd/ateapi/internal/authz/registry_test.go b/cmd/ateapi/internal/authz/registry_test.go index d823ca4bd3..3bb00074e9 100644 --- a/cmd/ateapi/internal/authz/registry_test.go +++ b/cmd/ateapi/internal/authz/registry_test.go @@ -299,6 +299,30 @@ func TestDefaultRPCPermissions(t *testing.T) { req: &ateapi.DeleteExternalVolumeClassRequest{ExternalVolumeClass: &ateapi.ObjectRef{Name: "nfs-gold"}}, want: []check{{RelationCanDelete, "external_volume_class:nfs-gold"}}, }, + { + name: "GetExternalVolumeClassAccessPolicy", + fullMethod: ateapi.Control_GetExternalVolumeClassAccessPolicy_FullMethodName, + req: &ateapi.GetExternalVolumeClassAccessPolicyRequest{ExternalVolumeClass: &ateapi.ObjectRef{Name: "nfs-gold"}}, + want: []check{{RelationCanGetAccessPolicy, "external_volume_class:nfs-gold"}}, + }, + { + name: "CreateExternalVolumeClassAccessPolicy", + fullMethod: ateapi.Control_CreateExternalVolumeClassAccessPolicy_FullMethodName, + req: &ateapi.CreateExternalVolumeClassAccessPolicyRequest{ExternalVolumeClass: &ateapi.ObjectRef{Name: "nfs-gold"}}, + want: []check{{RelationCanCreateAccessPolicy, "external_volume_class:nfs-gold"}}, + }, + { + name: "UpdateExternalVolumeClassAccessPolicy", + fullMethod: ateapi.Control_UpdateExternalVolumeClassAccessPolicy_FullMethodName, + req: &ateapi.UpdateExternalVolumeClassAccessPolicyRequest{ExternalVolumeClass: &ateapi.ObjectRef{Name: "nfs-gold"}}, + want: []check{{RelationCanUpdateAccessPolicy, "external_volume_class:nfs-gold"}}, + }, + { + name: "DeleteExternalVolumeClassAccessPolicy", + fullMethod: ateapi.Control_DeleteExternalVolumeClassAccessPolicy_FullMethodName, + req: &ateapi.DeleteExternalVolumeClassAccessPolicyRequest{ExternalVolumeClass: &ateapi.ObjectRef{Name: "nfs-gold"}}, + want: []check{{RelationCanDeleteAccessPolicy, "external_volume_class:nfs-gold"}}, + }, // Actor identity credentials. { @@ -629,6 +653,30 @@ func TestDefaultRPCPermissions_MalformedIdentifierFailsClosed(t *testing.T) { req: &ateapi.DeleteExternalVolumeClassRequest{ExternalVolumeClass: &ateapi.ObjectRef{Name: "nfs/gold"}}, wantField: "external_volume_class.name", }, + { + name: "GetExternalVolumeClassAccessPolicy without a class", + fullMethod: ateapi.Control_GetExternalVolumeClassAccessPolicy_FullMethodName, + req: &ateapi.GetExternalVolumeClassAccessPolicyRequest{}, + wantField: "external_volume_class.name", + }, + { + name: "CreateExternalVolumeClassAccessPolicy without a name", + fullMethod: ateapi.Control_CreateExternalVolumeClassAccessPolicy_FullMethodName, + req: &ateapi.CreateExternalVolumeClassAccessPolicyRequest{ExternalVolumeClass: &ateapi.ObjectRef{}}, + wantField: "external_volume_class.name", + }, + { + name: "UpdateExternalVolumeClassAccessPolicy with an invalid name", + fullMethod: ateapi.Control_UpdateExternalVolumeClassAccessPolicy_FullMethodName, + req: &ateapi.UpdateExternalVolumeClassAccessPolicyRequest{ExternalVolumeClass: &ateapi.ObjectRef{Name: "Nfs-Gold"}}, + wantField: "external_volume_class.name", + }, + { + name: "DeleteExternalVolumeClassAccessPolicy with an invalid name", + fullMethod: ateapi.Control_DeleteExternalVolumeClassAccessPolicy_FullMethodName, + req: &ateapi.DeleteExternalVolumeClassAccessPolicyRequest{ExternalVolumeClass: &ateapi.ObjectRef{Name: "nfs/gold"}}, + wantField: "external_volume_class.name", + }, { name: "MintActorJWT without an actor", fullMethod: ateapi.Control_MintActorJwt_FullMethodName, diff --git a/tools/apitool/internal/docsite/docsite.go b/tools/apitool/internal/docsite/docsite.go index b585649bca..842cfd4b08 100644 --- a/tools/apitool/internal/docsite/docsite.go +++ b/tools/apitool/internal/docsite/docsite.go @@ -219,7 +219,7 @@ func (b viewBuilder) resourceView(page resourcePage) resourceView { ParentAnchor: b.anchors.parentAnchor(page), Subresources: subresourceLinks(b.pages, page), Attrs: b.attrTree(page.Message.Fields), - Example: trimLicenseHeader(b.examples[page.Message.Name]), + Example: b.exampleFor(page), } for _, m := range page.Methods { rv.Methods = append(rv.Methods, b.methodView(page, m)) @@ -227,6 +227,15 @@ func (b viewBuilder) resourceView(page resourcePage) resourceView { return rv } +func (b viewBuilder) exampleFor(page resourcePage) string { + if page.Parent != "" { + if ex, ok := b.examples[page.Parent+"."+page.Message.Name]; ok { + return trimLicenseHeader(ex) + } + } + return trimLicenseHeader(b.examples[page.Message.Name]) +} + // trimLicenseHeader drops the comment lines that start example, its license // header. func trimLicenseHeader(example string) string { diff --git a/tools/apitool/internal/docsite/docsite_test.go b/tools/apitool/internal/docsite/docsite_test.go index 8764e0a425..1e0216f5bf 100644 --- a/tools/apitool/internal/docsite/docsite_test.go +++ b/tools/apitool/internal/docsite/docsite_test.go @@ -234,6 +234,25 @@ func TestRender_Definitions(t *testing.T) { } } +func TestRender_PerParentExampleOverride(t *testing.T) { + ex := map[string]string{ + "Widget": "# License.\n\nwidget: 1\n", + "Gadget": "gadget: 2\n", + "Widget.Gadget": "# License.\n\ngadget: widget-override\n", + } + out, err := docsite.Render(fixtureAPI(t), ex, fixtureK8sAPI, fixtureK8sExamples) + if err != nil { + t.Fatalf("Render() error = %v", err) + } + html := regexp.MustCompile(`]*)?>`).ReplaceAllString(string(out.Body), "") + if got := strings.Count(html, "
gadget: 2
"); got != 1 { + t.Errorf("default Gadget example rendered %d times, want 1 (Global page only)", got) + } + if got := strings.Count(html, "
gadget: widget-override
"); got != 1 { + t.Errorf("Widget.Gadget override rendered %d times, want 1", got) + } +} + func TestRender_MissingExample(t *testing.T) { out, err := docsite.Render(fixtureAPI(t), map[string]string{"Widget": `{}`}, fixtureK8sAPI, map[string]string{}) if err != nil { @@ -360,7 +379,7 @@ func TestRender_RealAPISmoke(t *testing.T) { if err != nil { t.Fatalf("Render() error = %v", err) } - for _, want := range []string{"substrate.ateapi.v1.Actor", `id="resource-ate.dev.v1.WorkerPool"`} { + for _, want := range []string{"substrate.ateapi.v1.Actor", `id="resource-ate.dev.v1.WorkerPool"`, "atespace:team-b"} { if !strings.Contains(string(out.Body), want) { t.Errorf("output does not mention %s", want) } diff --git a/tools/apitool/internal/docsite/pages.go b/tools/apitool/internal/docsite/pages.go index 4cade7687a..7ab8670b79 100644 --- a/tools/apitool/internal/docsite/pages.go +++ b/tools/apitool/internal/docsite/pages.go @@ -44,10 +44,10 @@ type resourcePage struct { // resourcePages lists one page per resource and parent, in api's message // order: a single page for a top-level resource, and one per parent for a -// subresource. For example, AccessPolicy has a page under Global and one -// under Atespace. It fails wherever model.Resources does, and on a custom -// method of a resource with several parents, since its parent can't be read -// from its name. +// subresource. For example, AccessPolicy has a page under Global, Atespace, +// and ExternalVolumeClass. It fails wherever model.Resources does, and on a +// custom method of a resource with several parents, since its parent can't be +// read from its name. func resourcePages(api *model.API) ([]resourcePage, error) { resources, err := model.Resources(api) if err != nil { diff --git a/tools/apitool/internal/docsite/pages_test.go b/tools/apitool/internal/docsite/pages_test.go index 57992b3e59..1398ad28ea 100644 --- a/tools/apitool/internal/docsite/pages_test.go +++ b/tools/apitool/internal/docsite/pages_test.go @@ -98,25 +98,34 @@ func TestResourcePages(t *testing.T) { []model.Method{ rpc("GetGlobalAccessPolicy", "AccessPolicy", "AccessPolicy"), rpc("GetAtespaceAccessPolicy", "AccessPolicy", "AccessPolicy"), + rpc("GetExternalVolumeClassAccessPolicy", "AccessPolicy", "AccessPolicy"), rpc("UpdateGlobalAccessPolicy", "AccessPolicy", "AccessPolicy"), }, resource("Atespace", model.ResourceAnnotation{Scope: ateapi.Scope_SCOPE_GLOBAL, Plural: "Atespaces"}), - resource("AccessPolicy", model.ResourceAnnotation{Parents: []string{"Global", "Atespace"}, Singleton: true, Plural: "AccessPolicies"}), + resource("ExternalVolumeClass", model.ResourceAnnotation{Scope: ateapi.Scope_SCOPE_GLOBAL, Plural: "ExternalVolumeClasses"}), + resource("AccessPolicy", model.ResourceAnnotation{Parents: []string{"Global", "Atespace", "ExternalVolumeClass"}, Singleton: true, Plural: "AccessPolicies"}), ), want: []resourcePage{ {Message: resource("Atespace", model.ResourceAnnotation{Scope: ateapi.Scope_SCOPE_GLOBAL, Plural: "Atespaces"}), Scope: "global"}, + {Message: resource("ExternalVolumeClass", model.ResourceAnnotation{Scope: ateapi.Scope_SCOPE_GLOBAL, Plural: "ExternalVolumeClasses"}), Scope: "global"}, { - Message: resource("AccessPolicy", model.ResourceAnnotation{Parents: []string{"Global", "Atespace"}, Singleton: true, Plural: "AccessPolicies"}), + Message: resource("AccessPolicy", model.ResourceAnnotation{Parents: []string{"Global", "Atespace", "ExternalVolumeClass"}, Singleton: true, Plural: "AccessPolicies"}), Parent: "Global", Singleton: true, Methods: []model.Method{method("GetGlobalAccessPolicy", "AccessPolicy", "AccessPolicy"), method("UpdateGlobalAccessPolicy", "AccessPolicy", "AccessPolicy")}, }, { - Message: resource("AccessPolicy", model.ResourceAnnotation{Parents: []string{"Global", "Atespace"}, Singleton: true, Plural: "AccessPolicies"}), + Message: resource("AccessPolicy", model.ResourceAnnotation{Parents: []string{"Global", "Atespace", "ExternalVolumeClass"}, Singleton: true, Plural: "AccessPolicies"}), Parent: "Atespace", Singleton: true, Methods: []model.Method{method("GetAtespaceAccessPolicy", "AccessPolicy", "AccessPolicy")}, }, + { + Message: resource("AccessPolicy", model.ResourceAnnotation{Parents: []string{"Global", "Atespace", "ExternalVolumeClass"}, Singleton: true, Plural: "AccessPolicies"}), + Parent: "ExternalVolumeClass", + Singleton: true, + Methods: []model.Method{method("GetExternalVolumeClassAccessPolicy", "AccessPolicy", "AccessPolicy")}, + }, }, }, } @@ -150,7 +159,8 @@ func TestResourcePages_Invalid(t *testing.T) { api: controlAPI( []model.Method{rpc("ResetAccessPolicy", "AccessPolicy", "AccessPolicy")}, resource("Atespace", model.ResourceAnnotation{Scope: ateapi.Scope_SCOPE_GLOBAL, Plural: "Atespaces"}), - resource("AccessPolicy", model.ResourceAnnotation{Parents: []string{"Global", "Atespace"}, Singleton: true, Plural: "AccessPolicies"}), + resource("ExternalVolumeClass", model.ResourceAnnotation{Scope: ateapi.Scope_SCOPE_GLOBAL, Plural: "ExternalVolumeClasses"}), + resource("AccessPolicy", model.ResourceAnnotation{Parents: []string{"Global", "Atespace", "ExternalVolumeClass"}, Singleton: true, Plural: "AccessPolicies"}), ), }, } diff --git a/tools/apitool/internal/examples/examples.go b/tools/apitool/internal/examples/examples.go index 7662c3fe9e..853ef0f904 100644 --- a/tools/apitool/internal/examples/examples.go +++ b/tools/apitool/internal/examples/examples.go @@ -17,9 +17,11 @@ // // grpc/ holds one file per gRPC resource as ate-api-server returns it, with // server-set fields such as uid and status. Each is its message's protojson -// form as YAML, named after the message, e.g. Actor.yaml. Tests check that -// every resource has an example and that each example parses as its message, -// so a renamed or removed field fails them. +// form as YAML, named after the message, e.g. Actor.yaml; a subresource with +// several parents may also add a per-parent override named +// "..yaml", e.g. ExternalVolumeClass.AccessPolicy.yaml. +// Tests check that every resource has an example and that each example parses +// as its message, so a renamed or removed field fails them. // // k8s/ holds one file per Kubernetes resource as users apply it with kubectl, // named after its kind, e.g. WorkerPool.yaml. Tests check each against its diff --git a/tools/apitool/internal/examples/examples_test.go b/tools/apitool/internal/examples/examples_test.go index e673559cf4..f12566937e 100644 --- a/tools/apitool/internal/examples/examples_test.go +++ b/tools/apitool/internal/examples/examples_test.go @@ -52,6 +52,18 @@ func resources(t *testing.T) map[string]model.Message { return byName } +func resolveGRPCExampleResource(name string, rs map[string]model.Message) (model.Message, bool) { + if parent, resName, hasDot := strings.Cut(name, "."); hasDot { + msg, ok := rs[resName] + if !ok || msg.ResourceAnnotation == nil || !slices.Contains(msg.ResourceAnnotation.Parents, parent) { + return model.Message{}, false + } + return msg, true + } + msg, ok := rs[name] + return msg, ok +} + func TestGRPCResources_OnePerResource(t *testing.T) { got, err := examples.GRPCResources() if err != nil { @@ -64,8 +76,8 @@ func TestGRPCResources_OnePerResource(t *testing.T) { } } for name := range got { - if _, ok := rs[name]; !ok { - t.Errorf("grpc/%s.yaml names no resource", name) + if _, ok := resolveGRPCExampleResource(name, rs); !ok { + t.Errorf("grpc/%s.yaml names no resource (or valid . subresource override)", name) } } } @@ -77,7 +89,7 @@ func TestGRPCResources_ParsesAsResource(t *testing.T) { } rs := resources(t) for _, name := range slices.Sorted(maps.Keys(got)) { - msg, ok := rs[name] + msg, ok := resolveGRPCExampleResource(name, rs) if !ok { continue // Reported by TestGRPCResources_OnePerResource. } diff --git a/tools/apitool/internal/examples/grpc/ExternalVolumeClass.AccessPolicy.yaml b/tools/apitool/internal/examples/grpc/ExternalVolumeClass.AccessPolicy.yaml new file mode 100644 index 0000000000..e118ab94c6 --- /dev/null +++ b/tools/apitool/internal/examples/grpc/ExternalVolumeClass.AccessPolicy.yaml @@ -0,0 +1,24 @@ +# Copyright 2026 The Agent Substrate Authors +# +# 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. +metadata: + name: default + uid: 9a0b1c2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d + version: "2" + createTime: "2026-06-01T00:05:00Z" + updateTime: "2026-08-10T16:30:00Z" +bindings: +- role: allowed_atespace + members: + - atespace:team-a + - atespace:team-b diff --git a/tools/apitool/internal/model/model.go b/tools/apitool/internal/model/model.go index c490a77df3..122d99f85f 100644 --- a/tools/apitool/internal/model/model.go +++ b/tools/apitool/internal/model/model.go @@ -146,8 +146,8 @@ func (m Message) IsResource() bool { type ResourceAnnotation struct { // Parents lists the resource types this resource is a subresource of: // another resource's message name, or GlobalParent. For example, - // ["Global", "Atespace"] for AccessPolicy; empty for the top-level - // Actor. + // ["Global", "Atespace", "ExternalVolumeClass"] for AccessPolicy; empty + // for the top-level Actor. Parents []string // Singleton is true if each parent has at most one instance of this // resource. For example, true for EgressPolicy. diff --git a/tools/apitool/internal/model/model_test.go b/tools/apitool/internal/model/model_test.go index 8f4c95e6c0..c2f2d076ae 100644 --- a/tools/apitool/internal/model/model_test.go +++ b/tools/apitool/internal/model/model_test.go @@ -245,19 +245,20 @@ func TestBuild_Annotations(t *testing.T) { "ExternalVolumeClass": {Scope: ateapi.Scope_SCOPE_GLOBAL, Plural: "ExternalVolumeClasses"}, "Worker": {Scope: ateapi.Scope_SCOPE_GLOBAL, Plural: "Workers"}, "ActorAssignment": {Parents: []string{"Worker"}, Plural: "ActorAssignments"}, - "AccessPolicy": {Parents: []string{"Global", "Atespace"}, Singleton: true, Plural: "AccessPolicies"}, + "AccessPolicy": {Parents: []string{"Global", "Atespace", "ExternalVolumeClass"}, Singleton: true, Plural: "AccessPolicies"}, } if diff := cmp.Diff(wantResources, gotResources); diff != "" { t.Errorf("resource annotations mismatch (-want +got):\n%s", diff) } wantMethods := map[protoreflect.Name]string{ - "GetActor": "Actor", - "SuspendActor": "Actor", - "GetActorEgressPolicy": "EgressPolicy", - "GetGlobalAccessPolicy": "AccessPolicy", - "GetAtespaceAccessPolicy": "AccessPolicy", - "ListWorkerActorAssignments": "ActorAssignment", + "GetActor": "Actor", + "SuspendActor": "Actor", + "GetActorEgressPolicy": "EgressPolicy", + "GetGlobalAccessPolicy": "AccessPolicy", + "GetAtespaceAccessPolicy": "AccessPolicy", + "GetExternalVolumeClassAccessPolicy": "AccessPolicy", + "ListWorkerActorAssignments": "ActorAssignment", } gotMethods := map[protoreflect.Name]string{} for _, svc := range api.Services { From 6c241cfea590716bbdf65cc5beb1f8c6c61d0a3c Mon Sep 17 00:00:00 2001 From: Vu Le Date: Fri, 13 Nov 2026 19:29:22 +0000 Subject: [PATCH 30/30] resource model & authorization docs for ExternalVolumeClass access policies Signed-off-by: Vu Le --- docs/guides/authorization.md | 9 +++++++-- docs/reference/resource-model.md | 4 ++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/guides/authorization.md b/docs/guides/authorization.md index 656ce542b3..fdc34c00e8 100644 --- a/docs/guides/authorization.md +++ b/docs/guides/authorization.md @@ -129,6 +129,8 @@ one **atespace**. | Create an actor from a tag (`sourceTag`) | ✅ | | ✅ | ✅ | | | Workers: get, list, list assignments | ✅ | ✅ | | | | | Workers: create, update, delete, drain | ✅ | | | | | +| External volume classes: get, list, get access policies | ✅ | ✅ | get only (allowed) | get only (allowed) | | +| External volume classes: create, delete, manage access policies | ✅ | | | | | ### System roles @@ -219,14 +221,17 @@ Workers have no atespace; their permissions come from the global scope. ### External volume classes External volume classes have no atespace; their permissions come from the -global scope. +global scope, and editors of atespaces granted `allowed_atespace` by a class's +access policy may read that class. | RPC | Permission, on | Allowed for | |---|---|---| | `CreateExternalVolumeClass` | `can_create_external_volume_class`, global | Global owner | | `ListExternalVolumeClasses` | `can_list_external_volume_classes`, global | Global viewer | -| `GetExternalVolumeClass` | `can_get`, the class | Global viewer | +| `GetExternalVolumeClass` | `can_get`, the class | Global viewer; editor of an allowed atespace | | `DeleteExternalVolumeClass` | `can_delete`, the class | Global owner | +| `GetExternalVolumeClassAccessPolicy` | `can_get_access_policy`, the class | Global viewer | +| `CreateExternalVolumeClassAccessPolicy`, `UpdateExternalVolumeClassAccessPolicy`, `DeleteExternalVolumeClassAccessPolicy` | `can_create_access_policy` / `can_update_access_policy` / `can_delete_access_policy`, the class | Global owner | ### WorkerService diff --git a/docs/reference/resource-model.md b/docs/reference/resource-model.md index 2e52690ec2..23d0b412f1 100644 --- a/docs/reference/resource-model.md +++ b/docs/reference/resource-model.md @@ -46,6 +46,7 @@ Global │ │ └── EgressPolicy "default" subresource (singleton) │ └── Tag ├── ExternalVolumeClass +│ └── AccessPolicy "default" subresource (singleton) └── Worker └── ActorAssignment subresource (one per hosted Actor, managed by Substrate) ``` @@ -68,6 +69,7 @@ Global | `EgressPolicy` | `Actor` | 0..1, named `default` | Clients | | `AccessPolicy` | Global | 0..1, named `default` | Clients | | `AccessPolicy` | `Atespace` | 0..1, named `default` | Clients | +| `AccessPolicy` | `ExternalVolumeClass` | 0..1, named `default` | Clients | | `ActorAssignment` | `Worker` | 0..N | Substrate | ## Kubernetes resources @@ -102,9 +104,11 @@ classDiagram class Worker class ActorAssignment class ExternalVolumeClass + class ExternalVolumeClassAccessPolicy } Atespace "1" *-- "0..1" AtespaceAccessPolicy + ExternalVolumeClass "1" *-- "0..1" ExternalVolumeClassAccessPolicy Atespace "1" o-- "*" ActorTemplate Atespace "1" o-- "*" Actor Atespace "1" o-- "*" Tag