From e1048dbcee5d80c1ccc4be9f3ea3737d26c10806 Mon Sep 17 00:00:00 2001 From: xing-yang Date: Tue, 12 Jul 2022 14:41:25 -0400 Subject: [PATCH] Add VolumeGroup and VolumeGroupSnapshot CSI RPCs --- csi.proto | 374 +++++++++++++++++++++++++++++++++++++++++++ spec.md | 469 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 843 insertions(+) diff --git a/csi.proto b/csi.proto index ee73aa7a..1ed27e3b 100644 --- a/csi.proto +++ b/csi.proto @@ -100,6 +100,51 @@ service Controller { returns (ControllerGetVolumeResponse) { option (alpha_method) = true; } + + rpc CreateVolumeGroup(CreateVolumeGroupRequest) + returns (CreateVolumeGroupResponse) { + option (alpha_method) = true; + } + + rpc CreateVolumeGroupSnapshot(CreateVolumeGroupSnapshotRequest) + returns (CreateVolumeGroupSnapshotResponse) { + option (alpha_method) = true; + } + + rpc ModifyVolumeGroup(ModifyVolumeGroupRequest) + returns (ModifyVolumeGroupResponse) { + option (alpha_method) = true; + } + + rpc DeleteVolumeGroup(DeleteVolumeGroupRequest) + returns (DeleteVolumeGroupResponse) } + option (alpha_method) = true; + } + + rpc DeleteVolumeGroupSnapshot(DeleteVolumeGroupSnapshotRequest) + returns (DeleteVolumeGroupSnapshotResponse) { + option (alpha_method) = true; + } + + rpc ListVolumeGroups(ListVolumeGroupsRequest) + returns (ListVolumeGroupsResponse) { + option (alpha_method) = true; + } + + rpc ListVolumeGroupSnapshots(ListVolumeGroupSnapshotsRequest) + returns (ListVolumeGroupSnapshotsResponse) { + option (alpha_method) = true; + } + + rpc GetVolumeGroup(GetVolumeGroupRequest) + returns (GetVolumeGroupResponse) { + option (alpha_method) = true; + } + + rpc GetVolumeGroupSnapshot(GetVolumeGroupSnapshotRequest) + returns (GetVolumeGroupSnapshotResponse) { + option (alpha_method) = true; + } } service Node { @@ -1008,6 +1053,303 @@ message GetCapacityResponse { google.protobuf.Int64Value minimum_volume_size = 3 [(alpha_field) = true]; } +message CreateVolumeGroupRequest { + option (alpha_message) = true; + + // suggested name for volume group (required for idempotency) + // This field is REQUIRED. + string name = 1; + + // params passed from VolumeGroupClass + // This field is OPTIONAL. + map parameters = 2; + + // Secrets required by plugin to complete volume group creation + // request. + // This field is OPTIONAL. Refer to the `Secrets Requirements` + // section on how to use this field. + map secrets = 3 [(csi_secret) = true]; + + // Phase 2 + // If specified, a volume group will be created from the source group + // snapshot. + // This field is OPTIONAL. + // VolumeGroupSnapshot source_volume_group_snapshot = 4; + + // Phase 2 + // If specified, a volume group will be created from a list of + // existing volumes. + // This field is OPTIONAL. + // repeated string volume_id = 5; +} + +message CreateVolumeGroupResponse { + option (alpha_message) = true; + + // Contains all attributes of the newly created volume group. + // This field is REQUIRED. + VolumeGroup volume_group = 1; +} + +message VolumeGroup { + option (alpha_message) = true; + + // The identifier for this volume group, generated by the plugin. + // This field is REQUIRED. + string volume_group_id = 1; + + // Opaque static properties of the volume group. + // This field is OPTIONAL. + map volume_group_context = 2; + + // Underlying volumes in this group. The same definition in CSI + // Volume. + // This field is REQUIRED. + // To support the creation of an empty group, this list can be empty. + // However, this field is not empty in the following cases: + // - Response from ListVolumeGroups or GetVolumeGroup if the + // VolumeGroup is not empty. + // - Response from ModifyVolumeGroup if the VolumeGroup is not + // empty after modification. + // - Phase 2: Create a new volume group from a source group snapshot. + // - Phase 2: Create a new volume group and add a list of existing + // volumes to the group. + repeated .csi.v1.Volume volumes = 3; +} +message DeleteVolumeGroupRequest { + option (alpha_message) = true; + + // The ID of the volume group to be deprovisioned. + // This field is REQUIRED. + string volume_group_id = 1; + + // Secrets required by plugin to complete volume group deletion + // request. + // This field is OPTIONAL. Refer to the `Secrets Requirements` + // section on how to use this field. + map secrets = 2 [(csi_secret) = true]; +} + +message DeleteVolumeGroupResponse { + option (alpha_message) = true; + // Intentionally empty. +} +message ModifyVolumeGroupRequest { + option (alpha_message) = true; + + // The ID of the volume group to be modified. + // This field is REQUIRED. + string volume_group_id = 1; + + // Specify volume_ids that will be in the modified volume group. + // This list will be compared with the volume_ids in the existing + // group. + // New ones will be added and missing ones will be removed. + // If no volume_ids are provided, all existing volumes will + // be removed from the group. + // This field is OPTIONAL. + repeated string volume_ids = 3; +} + +message ModifyVolumeGroupResponse { + option (alpha_message) = true; + + // Contains all attributes of the modified volume group. + // This field is REQUIRED. + VolumeGroup volume_group = 1; +} +message ControllerGetVolumeGroupRequest { + option (alpha_message) = true; + + // The ID of the volume group to fetch current volume group + // information for. + // This field is REQUIRED. + string volume_group_id = 1; +} + +message ControllerGetVolumeGroupResponse { + option (alpha_message) = true; + + // This field is REQUIRED + VolumeGroup volume_group = 1; +} +message ListVolumeGroupsRequest { + option (alpha_message) = true; + + // If specified (non-zero value), the Plugin MUST NOT return more + // entries than this number in the response. If the actual number of + // entries is more than this number, the Plugin MUST set `next_token` + // in the response which can be used to get the next page of entries + // in the subsequent `ListVolumeGroups` call. This field is OPTIONAL. + // If not specified (zero value), it means there is no restriction on + // the number of entries that can be returned. + // The value of this field MUST NOT be negative. + int32 max_entries = 1; + + // A token to specify where to start paginating. Set this field to + // `next_token` returned by a previous `ListVolumeGroups` call to get + // the next page of entries. This field is OPTIONAL. + // An empty string is equal to an unspecified field value. + string starting_token = 2; +} + +message ListVolumeGroupsResponse { + option (alpha_message) = true; + + message Entry { + // This field is REQUIRED + VolumeGroup volume_group = 1; + } + + repeated Entry entries = 1; + + // This token allows you to get the next page of entries for + // `ListVolumeGroups` request. If the number of entries is larger than + // `max_entries`, use the `next_token` as a value for the + // `starting_token` field in the next `ListVolumeGroups` request. This + // field is OPTIONAL. + // An empty string is equal to an unspecified field value. + string next_token = 2; +} +message CreateVolumeGroupSnapshotRequest { + option (alpha_message) = true; + + // suggested name for a group snapshot (required for idempotent) + // This field is REQUIRED. + string name = 1; + + // identifier indicates which volume group is used to take + // group snapshot + // This field is REQUIRED. + string source_volume_group_id = 2; + + // volume ids of the volumes in the source group. This field is + // REQUIRED. This is needed because some storage systems does not + // have a group persisted on the storage system until the time to + // take a group snapshot + repeated string volume_ids = 3; + + // secrets required for snapshot creation (pulled from + // VolumeSnapshotClass) + // This field is OPTIONAL. + map secrets = 4 [(.csi.v1.csi_secret) = true]; + + // params passed from VolumeSnapshotClass + // This field is OPTIONAL. + map parameters = 5; +} + +message CreateVolumeGroupSnapshotResponse { + option (alpha_message) = true; + + // Contains all attributes of the newly created group snapshot. + // This field is REQUIRED. + VolumeGroupSnapshot group_snapshot = 1; +} + +message VolumeGroupSnapshot { + option (alpha_message) = true; + + // The identifier for this group snapshot, generated by the plugin. + // This field is REQUIRED. + string group_snapshot_id = 1; + + // A list of snapshots created. Snapshot is the same + // definition as Snapshot definition used in CSI. + // This field is OPTIONAL. + repeated .csi.v1.Snapshot snapshots = 2; + + // Identity information for the source volume group. Currently, only + // support the case that source is volume group. This field is + // REQUIRED. + string source_volume_group_id = 3; + + // Indicates if a list of group snapshots are ready. + // This field is REQUIRED. + bool ready_to_use = 4; + + // Timestamp when the point-in-time consistency group snapshot is + // taken. + // This field is REQUIRED. + .google.protobuf.Timestamp creation_time = 5; + + // Complete total size of the snapshots in group in bytes. The purpose + // of this field is to give CO guidance on how much space is needed to + // restore volumes from all snapshots in group. + // This field is OPTIONAL. + int64 size_bytes = 6; +} +message DeleteVolumeGroupSnapshotRequest { + option (alpha_message) = true; + + // The ID of the group snapshot to be deprovisioned. + // This field is REQUIRED. + string group_snapshot_id = 1; + + // Secrets required by plugin to complete group snapshot deletion + // request. + // This field is OPTIONAL. Refer to the `Secrets Requirements` + // section on how to use this field. + map secrets = 2 [(csi_secret) = true]; +} + +message DeleteVolumeGroupSnapshotResponse { + // Intentionally empty. +} +message ControllerGetVolumeGroupSnapshotRequest { + option (alpha_message) = true; + + // The ID of the group snapshot to fetch current group snapshot + // information for. + // This field is REQUIRED. + string group_snapshot_id = 1; +} + +message ControllerGetVolumeGroupSnapshotResponse { + option (alpha_message) = true; + + // This field is REQUIRED + VolumeGroupSnapshot group_snapshot = 1; +} +message ListVolumeGroupSnapshotsRequest { + option (alpha_message) = true; + + // If specified (non-zero value), the Plugin MUST NOT return more + // entries than this number in the response. If the actual number of + // entries is more than this number, the Plugin MUST set `next_token` + // in the response which can be used to get the next page of entries + // in the subsequent `ListVolumeGroupSnapshots` call. + // This field is OPTIONAL. If not specified (zero value), it means + // there is no restriction on the number of entries that can be + // returned. The value of this field MUST NOT be negative. + int32 max_entries = 1; + + // A token to specify where to start paginating. Set this field to + // `next_token` returned by a previous `ListVolumeGroupSnapshots` + // call to get the next page of entries. This field is OPTIONAL. + // An empty string is equal to an unspecified field value. + string starting_token = 2; +} + +message ListVolumeGroupSnapshotsResponse { + option (alpha_message) = true; + + message Entry { + // This field is REQUIRED + VolumeGroupSnapshot group_snapshot = 1; + } + + repeated Entry entries = 1; + + // This token allows you to get the next page of entries for + // `ListVolumeGroupSnapshots` request. If the number of entries is + // larger than `max_entries`, use the `next_token` as a value for the + // `starting_token` field in the next `ListVolumeGroupSnapshots` + // request. + // This field is OPTIONAL. + // An empty string is equal to an unspecified field value. + string next_token = 2; +} message ControllerGetCapabilitiesRequest { // Intentionally empty. } @@ -1080,6 +1422,38 @@ message ControllerServiceCapability { // SINGLE_NODE_SINGLE_WRITER and/or SINGLE_NODE_MULTI_WRITER are // supported, in order to permit older COs to continue working. SINGLE_NODE_MULTI_WRITER = 13 [(alpha_enum_value) = true]; + + // Indicates that the controller plugin supports creating and + // deleting a volume group. + CREATE_DELETE_VOLUME_GROUP = 14 [(alpha_enum_value) = true]; + + // Indicates that the controller plugin supports adding an + // existing volume to a volume group and removing a volume from + // a volume group without deleting it. + VOLUME_GROUP_ADD_REMOVE_EXISTING_VOLUME = 15 + [(alpha_enum_value) = true]; + + // Indicates whether the controller plugin supports creating a + // volume from an individual volume snapshot if the volume + // snapshot is part of a VolumeGroupSnapshot. + // Use cases: selective restore, advanced recovery, etc. + INDIVIDUAL_SNAPSHOT_RESTORE = 16 [(alpha_enum_value) = true]; + + // Indicates that the controller plugin supports getting details + // of a volume group. + GET_VOLUME_GROUP = 17 [(alpha_enum_value) = true]; + + // Indicates that the controller plugin supports getting details + // of a volume group snapshot. + GET_VOLUME_GROUP_SNAPSHOT = 18 [(alpha_enum_value) = true]; + + // Indicates that the controller plugin supports getting details + // of a list of volume groups. + LIST_VOLUME_GROUPS = 19 [(alpha_enum_value) = true]; + + // Indicates that the controller plugin supports getting details + // of a list of volume group snapshots. + LIST_VOLUME_GROUP_SNAPSHOTS = 20 [(alpha_enum_value) = true]; } Type type = 1; diff --git a/spec.md b/spec.md index bd537fee..0f6bc4d7 100644 --- a/spec.md +++ b/spec.md @@ -381,6 +381,51 @@ service Controller { returns (ControllerGetVolumeResponse) { option (alpha_method) = true; } + + rpc CreateVolumeGroup(CreateVolumeGroupRequest) + returns (CreateVolumeGroupResponse) { + option (alpha_method) = true; + } + + rpc CreateVolumeGroupSnapshot(CreateVolumeGroupSnapshotRequest) + returns (CreateVolumeGroupSnapshotResponse) { + option (alpha_method) = true; + } + + rpc ModifyVolumeGroup(ModifyVolumeGroupRequest) + returns (ModifyVolumeGroupResponse) { + option (alpha_method) = true; + } + + rpc DeleteVolumeGroup(DeleteVolumeGroupRequest) + returns (DeleteVolumeGroupResponse) } + option (alpha_method) = true; + } + + rpc DeleteVolumeGroupSnapshot(DeleteVolumeGroupSnapshotRequest) + returns (DeleteVolumeGroupSnapshotResponse) { + option (alpha_method) = true; + } + + rpc ListVolumeGroups(ListVolumeGroupsRequest) + returns (ListVolumeGroupsResponse) { + option (alpha_method) = true; + } + + rpc ListVolumeGroupSnapshots(ListVolumeGroupSnapshotsRequest) + returns (ListVolumeGroupSnapshotsResponse) { + option (alpha_method) = true; + } + + rpc GetVolumeGroup(GetVolumeGroupRequest) + returns (GetVolumeGroupResponse) { + option (alpha_method) = true; + } + + rpc GetVolumeGroupSnapshot(GetVolumeGroupSnapshotRequest) + returns (GetVolumeGroupSnapshotResponse) { + option (alpha_method) = true; + } } service Node { @@ -1663,6 +1708,398 @@ message GetCapacityResponse { If the plugin is unable to complete the GetCapacity call successfully, it MUST return a non-ok gRPC code in the gRPC status. +#### `CreateVolumeGroup` + +**ALPHA FEATURE** + +This RPC will be called by the CO to create a new volume group on behalf of a user. This operation MUST be idempotent. If a volume group corresponding to the specified volume group name already exists, is compatible with the specified parameters in the CreateVolumeGroupRequest, the Plugin MUST reply 0 OK with the corresponding CreateVolumeGroupResponse. CSI Plugins MAY create the following types of volume groups: + +Create a new empty volume group. +After the empty group is created, create a new volume, specifying the group name in the volume. +At restore time, create a single volume from individual snapshot and then join an existing group. +Create an empty group. +Create a volume from snapshot, specifying the group name in the volume. +Phase 2: Create a new volume group from a source group snapshot. +Phase 2: Create a new volume group and add a list of existing volumes to the group. +The following is non-goal: + +Non goal: Create a new group and at the same time create a list of new volumes in the group. +In VolumeGroupSnapshot message, snapshots is an optional field while group_snapshot_id is a required field. It is fine to only specify group_snapshot_id but not snapshots in VolumeGroupSnapshot message at restore time. However, the Plugin MUST return a list of volumes that are restored in CreateVolumeGroupResponse. + +```protobuf +message CreateVolumeGroupRequest { + option (alpha_message) = true; + + // suggested name for volume group (required for idempotency) + // This field is REQUIRED. + string name = 1; + + // params passed from VolumeGroupClass + // This field is OPTIONAL. + map parameters = 2; + + // Secrets required by plugin to complete volume group creation + // request. + // This field is OPTIONAL. Refer to the `Secrets Requirements` + // section on how to use this field. + map secrets = 3 [(csi_secret) = true]; + + // Phase 2 + // If specified, a volume group will be created from the source group + // snapshot. + // This field is OPTIONAL. + // VolumeGroupSnapshot source_volume_group_snapshot = 4; + + // Phase 2 + // If specified, a volume group will be created from a list of + // existing volumes. + // This field is OPTIONAL. + // repeated string volume_id = 5; +} + +message CreateVolumeGroupResponse { + option (alpha_message) = true; + + // Contains all attributes of the newly created volume group. + // This field is REQUIRED. + VolumeGroup volume_group = 1; +} + +message VolumeGroup { + option (alpha_message) = true; + + // The identifier for this volume group, generated by the plugin. + // This field is REQUIRED. + string volume_group_id = 1; + + // Opaque static properties of the volume group. + // This field is OPTIONAL. + map volume_group_context = 2; + + // Underlying volumes in this group. The same definition in CSI + // Volume. + // This field is REQUIRED. + // To support the creation of an empty group, this list can be empty. + // However, this field is not empty in the following cases: + // - Response from ListVolumeGroups or GetVolumeGroup if the + // VolumeGroup is not empty. + // - Response from ModifyVolumeGroup if the VolumeGroup is not + // empty after modification. + // - Phase 2: Create a new volume group from a source group snapshot. + // - Phase 2: Create a new volume group and add a list of existing + // volumes to the group. + repeated .csi.v1.Volume volumes = 3; +} +``` + +#### `CreateVolume` + +TODO + +#### `DeleteVolumeGroup` + +**ALPHA FEATURE** + +```protobuf +message DeleteVolumeGroupRequest { + option (alpha_message) = true; + + // The ID of the volume group to be deprovisioned. + // This field is REQUIRED. + string volume_group_id = 1; + + // Secrets required by plugin to complete volume group deletion + // request. + // This field is OPTIONAL. Refer to the `Secrets Requirements` + // section on how to use this field. + map secrets = 2 [(csi_secret) = true]; +} + +message DeleteVolumeGroupResponse { + option (alpha_message) = true; + // Intentionally empty. +} +``` + +#### `ModifyVolumeGroup` + +**ALPHA FEATURE** + +This RPC will be called by the CO to modify an existing volumegroup on behalf of a user. volume_ids provided in the ModifyVolumeGroupRequest will be compared to the ones in the existing VolumeGroup. New volume_ids in the modified VolumeGroup will be added to the VolumeGroup. Existing volume_ids not in the modified VolumeGroup will be removed from the VolumeGroup. If volume_ids is empty, the VolumeGroup will be removed of all existing volumes. This operation MUST be idempotent. + +To support ModifyVolumeGroup, the Kubernetes VolumeGroup controller will be implemented to have a desired state of the world and an actual state of the world. The desired state of the world contains VolumeGroups with the desired PVCList while the actual state of the world contains VolumeGroups with the actual PVCList. The controller will try to reconcile the two by handling adding and removing multiple PVCs through a single CSI RPC call each time. + +Note that filesystems based storage systems may not be able to support this RPC. For block based storage systems, this is a very convenient method. However, it may not satisfy the requirement for consistency as the volume is created without the knowledge of which group it is placed in. It is out of the scope of the CSI spec to determine whether a group is consistent or not. It is up to the storage provider to clarify that in the vendor specific documentation. + +CSI drivers supporting VOLUME_GROUP_ADD_REMOVE_EXISTING_VOLUME MUST implement ModifyVolumeGroup RPC. + +```protobuf +message ModifyVolumeGroupRequest { + option (alpha_message) = true; + + // The ID of the volume group to be modified. + // This field is REQUIRED. + string volume_group_id = 1; + + // Specify volume_ids that will be in the modified volume group. + // This list will be compared with the volume_ids in the existing + // group. + // New ones will be added and missing ones will be removed. + // If no volume_ids are provided, all existing volumes will + // be removed from the group. + // This field is OPTIONAL. + repeated string volume_ids = 3; +} + +message ModifyVolumeGroupResponse { + option (alpha_message) = true; + + // Contains all attributes of the modified volume group. + // This field is REQUIRED. + VolumeGroup volume_group = 1; +} +``` + +#### `ControllerGetVolumeGroup` + +**ALPHA FEATURE** + +```protobuf +message ControllerGetVolumeGroupRequest { + option (alpha_message) = true; + + // The ID of the volume group to fetch current volume group + // information for. + // This field is REQUIRED. + string volume_group_id = 1; +} + +message ControllerGetVolumeGroupResponse { + option (alpha_message) = true; + + // This field is REQUIRED + VolumeGroup volume_group = 1; +} +``` + +#### `ListVolumeGroups` + +**ALPHA FEATURE** + +```protobuf +message ListVolumeGroupsRequest { + option (alpha_message) = true; + + // If specified (non-zero value), the Plugin MUST NOT return more + // entries than this number in the response. If the actual number of + // entries is more than this number, the Plugin MUST set `next_token` + // in the response which can be used to get the next page of entries + // in the subsequent `ListVolumeGroups` call. This field is OPTIONAL. + // If not specified (zero value), it means there is no restriction on + // the number of entries that can be returned. + // The value of this field MUST NOT be negative. + int32 max_entries = 1; + + // A token to specify where to start paginating. Set this field to + // `next_token` returned by a previous `ListVolumeGroups` call to get + // the next page of entries. This field is OPTIONAL. + // An empty string is equal to an unspecified field value. + string starting_token = 2; +} + +message ListVolumeGroupsResponse { + option (alpha_message) = true; + + message Entry { + // This field is REQUIRED + VolumeGroup volume_group = 1; + } + + repeated Entry entries = 1; + + // This token allows you to get the next page of entries for + // `ListVolumeGroups` request. If the number of entries is larger than + // `max_entries`, use the `next_token` as a value for the + // `starting_token` field in the next `ListVolumeGroups` request. This + // field is OPTIONAL. + // An empty string is equal to an unspecified field value. + string next_token = 2; +} +``` + +#### `CreateVolumeGroupSnapshot` + +**ALPHA FEATURE** + +The purpose of this call is to request the creation of a multi-volume snapshot. Group snapshots can be created from existing volume group. Note that calls to this function must be idempotent - the function may be called multiple times for the same name - the group snapshot must only be created once. + +```protobuf +message CreateVolumeGroupSnapshotRequest { + option (alpha_message) = true; + + // suggested name for a group snapshot (required for idempotent) + // This field is REQUIRED. + string name = 1; + + // identifier indicates which volume group is used to take + // group snapshot + // This field is REQUIRED. + string source_volume_group_id = 2; + + // volume ids of the volumes in the source group. This field is + // REQUIRED. This is needed because some storage systems does not + // have a group persisted on the storage system until the time to + // take a group snapshot + repeated string volume_ids = 3; + + // secrets required for snapshot creation (pulled from + // VolumeSnapshotClass) + // This field is OPTIONAL. + map secrets = 4 [(.csi.v1.csi_secret) = true]; + + // params passed from VolumeSnapshotClass + // This field is OPTIONAL. + map parameters = 5; +} + +message CreateVolumeGroupSnapshotResponse { + option (alpha_message) = true; + + // Contains all attributes of the newly created group snapshot. + // This field is REQUIRED. + VolumeGroupSnapshot group_snapshot = 1; +} + +message VolumeGroupSnapshot { + option (alpha_message) = true; + + // The identifier for this group snapshot, generated by the plugin. + // This field is REQUIRED. + string group_snapshot_id = 1; + + // A list of snapshots created. Snapshot is the same + // definition as Snapshot definition used in CSI. + // This field is OPTIONAL. + repeated .csi.v1.Snapshot snapshots = 2; + + // Identity information for the source volume group. Currently, only + // support the case that source is volume group. This field is + // REQUIRED. + string source_volume_group_id = 3; + + // Indicates if a list of group snapshots are ready. + // This field is REQUIRED. + bool ready_to_use = 4; + + // Timestamp when the point-in-time consistency group snapshot is + // taken. + // This field is REQUIRED. + .google.protobuf.Timestamp creation_time = 5; + + // Complete total size of the snapshots in group in bytes. The purpose + // of this field is to give CO guidance on how much space is needed to + // restore volumes from all snapshots in group. + // This field is OPTIONAL. + int64 size_bytes = 6; +} +``` + +#### `CreateSnapshot` + +TODO + +#### `DeleteVolumeGroupSnapshot` + +**ALPHA FEATURE** + +```protobuf +message DeleteVolumeGroupSnapshotRequest { + option (alpha_message) = true; + + // The ID of the group snapshot to be deprovisioned. + // This field is REQUIRED. + string group_snapshot_id = 1; + + // Secrets required by plugin to complete group snapshot deletion + // request. + // This field is OPTIONAL. Refer to the `Secrets Requirements` + // section on how to use this field. + map secrets = 2 [(csi_secret) = true]; +} + +message DeleteVolumeGroupSnapshotResponse { + // Intentionally empty. +} +``` + +#### `ControllerGetVolumeGroupSnapshot` + +**ALPHA FEATURE** + +```protobuf +message ControllerGetVolumeGroupSnapshotRequest { + option (alpha_message) = true; + + // The ID of the group snapshot to fetch current group snapshot + // information for. + // This field is REQUIRED. + string group_snapshot_id = 1; +} + +message ControllerGetVolumeGroupSnapshotResponse { + option (alpha_message) = true; + + // This field is REQUIRED + VolumeGroupSnapshot group_snapshot = 1; +} +``` + +#### `ListVolumeGroupSnapshots` + +**ALPHA FEATURE** + +```protobuf +message ListVolumeGroupSnapshotsRequest { + option (alpha_message) = true; + + // If specified (non-zero value), the Plugin MUST NOT return more + // entries than this number in the response. If the actual number of + // entries is more than this number, the Plugin MUST set `next_token` + // in the response which can be used to get the next page of entries + // in the subsequent `ListVolumeGroupSnapshots` call. + // This field is OPTIONAL. If not specified (zero value), it means + // there is no restriction on the number of entries that can be + // returned. The value of this field MUST NOT be negative. + int32 max_entries = 1; + + // A token to specify where to start paginating. Set this field to + // `next_token` returned by a previous `ListVolumeGroupSnapshots` + // call to get the next page of entries. This field is OPTIONAL. + // An empty string is equal to an unspecified field value. + string starting_token = 2; +} + +message ListVolumeGroupSnapshotsResponse { + option (alpha_message) = true; + + message Entry { + // This field is REQUIRED + VolumeGroupSnapshot group_snapshot = 1; + } + + repeated Entry entries = 1; + + // This token allows you to get the next page of entries for + // `ListVolumeGroupSnapshots` request. If the number of entries is + // larger than `max_entries`, use the `next_token` as a value for the + // `starting_token` field in the next `ListVolumeGroupSnapshots` + // request. + // This field is OPTIONAL. + // An empty string is equal to an unspecified field value. + string next_token = 2; +} +``` + #### `ControllerGetCapabilities` A Controller Plugin MUST implement this RPC call. This RPC allows the CO to check the supported capabilities of controller service provided by the Plugin. @@ -1740,6 +2177,38 @@ message ControllerServiceCapability { // SINGLE_NODE_SINGLE_WRITER and/or SINGLE_NODE_MULTI_WRITER are // supported, in order to permit older COs to continue working. SINGLE_NODE_MULTI_WRITER = 13 [(alpha_enum_value) = true]; + + // Indicates that the controller plugin supports creating and + // deleting a volume group. + CREATE_DELETE_VOLUME_GROUP = 14 [(alpha_enum_value) = true]; + + // Indicates that the controller plugin supports adding an + // existing volume to a volume group and removing a volume from + // a volume group without deleting it. + VOLUME_GROUP_ADD_REMOVE_EXISTING_VOLUME = 15 + [(alpha_enum_value) = true]; + + // Indicates whether the controller plugin supports creating a + // volume from an individual volume snapshot if the volume + // snapshot is part of a VolumeGroupSnapshot. + // Use cases: selective restore, advanced recovery, etc. + INDIVIDUAL_SNAPSHOT_RESTORE = 16 [(alpha_enum_value) = true]; + + // Indicates that the controller plugin supports getting details + // of a volume group. + GET_VOLUME_GROUP = 17 [(alpha_enum_value) = true]; + + // Indicates that the controller plugin supports getting details + // of a volume group snapshot. + GET_VOLUME_GROUP_SNAPSHOT = 18 [(alpha_enum_value) = true]; + + // Indicates that the controller plugin supports getting details + // of a list of volume groups. + LIST_VOLUME_GROUPS = 19 [(alpha_enum_value) = true]; + + // Indicates that the controller plugin supports getting details + // of a list of volume group snapshots. + LIST_VOLUME_GROUP_SNAPSHOTS = 20 [(alpha_enum_value) = true]; } Type type = 1;