You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Define a standard that will enable storage vendors (SP) to develop
controllers/plugins for DR or to talk to the different CO systems.
Goals in MVP
The new standard will
Provide API at volume level granularity.
Enable SP authors to write one replication compliant plugin that “just works”
across all COs that implement RPC.
Define API (RPCs) that enable:
Enable/Disable volume replication.
Promote/Demote volume.
Resync volume to solve the issue before using the volume.
Non-Goals in MVP
Replication at different granular levels
Replication of volume snapshots.
Solution Overview
This specification defines an interface along with the minimum operational and
packaging recommendations for a storage provider (SP) to implement a
Replication compatible plugin. The interface declares the RPCs that a plugin
MUST expose.
Architecture
RPC Interface
Controller Service: The Controller plugin MUST implement these sets of
RPCs.
syntax="proto3";
packagereplication;
import"github.com/container-storage-interface/spec/lib/go/csi/csi.proto";
import"google/protobuf/descriptor.proto";
import"google/protobuf/duration.proto";
import"google/protobuf/timestamp.proto";
optiongo_package=".;replication";
extendgoogle.protobuf.FieldOptions {
// Indicates that this field is OPTIONAL and part of an experimental// API that may be deprecated and eventually removed between minor// releases.boolalpha_field=1100;
}
// Controller holds the RPC methods for replication and all the methods it// exposes should be idempotent.serviceController {
// EnableVolumeReplication RPC call to enable the volume replication.rpcEnableVolumeReplication (EnableVolumeReplicationRequest)
returns (EnableVolumeReplicationResponse) {}
// DisableVolumeReplication RPC call to disable the volume replication.rpcDisableVolumeReplication (DisableVolumeReplicationRequest)
returns (DisableVolumeReplicationResponse) {}
// PromoteVolume RPC call to promote the volume.rpcPromoteVolume (PromoteVolumeRequest)
returns (PromoteVolumeResponse) {}
// DemoteVolume RPC call to demote the volume.rpcDemoteVolume (DemoteVolumeRequest)
returns (DemoteVolumeResponse) {}
// ResyncVolume RPC call to resync the volume.rpcResyncVolume (ResyncVolumeRequest)
returns (ResyncVolumeResponse) {}
// GetVolumeReplicationInfo RPC call to get the volume replication// information.rpcGetVolumeReplicationInfo (GetVolumeReplicationInfoRequest)
returns (GetVolumeReplicationInfoResponse) {}
// GetReplicationDestinationInfo RPC call to get the destination// volume or volume group details for an existing replication.rpcGetReplicationDestinationInfo (GetReplicationDestinationInfoRequest)
returns (GetReplicationDestinationInfoResponse) {}
}
EnableVolumeReplication
// EnableVolumeReplicationRequest holds the required information to enable// replication on a volume.messageEnableVolumeReplicationRequest {
// Deprecated "volume_id".reserved1;
reserved"volume_id";
// Plugin specific parameters passed in as opaque key-value pairs.map<string, string> parameters=2;
// Secrets required by the plugin to complete the request.map<string, string> secrets=3 [(csi.v1.csi_secret) = true];
// This field is OPTIONAL.// This field MUST contain enough information to uniquely identify// this specific replication// vs all other replications supported by this plugin.stringreplication_id=4 [(alpha_field) = true];
// If specified, this field will contain volume or volume group id// for replication.ReplicationSourcereplication_source=5;
}
// EnableVolumeReplicationResponse holds the information to send when// replication is successfully enabled on a volume.messageEnableVolumeReplicationResponse {
}
Error Scheme
Condition
gRPC Code
Description
Recovery Behavior
Missing required field
3 INVALID_ARGUMENT
Indicates that a required field is missing from the request.
Caller MUST fix the request by adding the missing required field before retrying.
Replication Source does not exist
5 NOT_FOUND
Indicates that the specified source does not exist.
Caller MUST verify that the replication_source is correct, the source is accessible, and has not been deleted before retrying with exponential back off.
Operation pending for Replication Source
10 ABORTED
Indicates that there is already an operation pending for the specified replication_source. In general the Cluster Orchestrator (CO) is responsible for ensuring that there is no more than one call "in-flight" per replication_source at a given time. However, in some circumstances, the CO MAY lose state (for example when the CO crashes and restarts), and MAY issue multiple calls simultaneously for the same replication_source. The Plugin, SHOULD handle this as gracefully as possible, and MAY return this error code to reject secondary calls.
Caller SHOULD ensure that there are no other calls pending for the specified replication_source, and then retry with exponential back off.
Not authenticated
16 UNAUTHENTICATED
The invoked RPC does not carry secrets that are valid for authentication.
Caller SHALL either fix the secrets provided in the RPC, or otherwise regalvanize said secrets such that they will pass authentication by the Plugin for the attempted RPC, after which point the caller MAY retry the attempted RPC.
Error is Unknown
2 UNKNOWN
Indicates that a unknown error is generated
Caller MUST study the logs before retrying
DisableVolumeReplication
// DisableVolumeReplicationRequest holds the required information to disable// replication on a volume.messageDisableVolumeReplicationRequest {
// Deprecated "volume_id".reserved1;
reserved"volume_id";
// Plugin specific parameters passed in as opaque key-value pairs.map<string, string> parameters=2;
// Secrets required by the plugin to complete the request.map<string, string> secrets=3 [(csi.v1.csi_secret) = true];
// This field is OPTIONAL.// This field MUST contain enough information to uniquely identify// this specific replication// vs all other replications supported by this plugin.stringreplication_id=4 [(alpha_field) = true];
// If specified, this field will contain volume or volume group id// for replication.ReplicationSourcereplication_source=5;
}
// DisableVolumeReplicationResponse holds the information to send when// replication is successfully disabled on a volume.messageDisableVolumeReplicationResponse {
}
Error Scheme
Condition
gRPC Code
Description
Recovery Behavior
Missing required field
3 INVALID_ARGUMENT
Indicates that a required field is missing from the request.
Caller MUST fix the request by adding the missing required field before retrying.
Replication Source does not exist
5 NOT_FOUND
Indicates that the specified source does not exist.
Caller MUST verify that the replication_source is correct, the source is accessible, and has not been deleted before retrying with exponential back off.
Operation pending for Replication Source
10 ABORTED
Indicates that there is already an operation pending for the specified replication_source. In general the Cluster Orchestrator (CO) is responsible for ensuring that there is no more than one call "in-flight" per replication_source at a given time. However, in some circumstances, the CO MAY lose state (for example when the CO crashes and restarts), and MAY issue multiple calls simultaneously for the same replication_source. The Plugin, SHOULD handle this as gracefully as possible, and MAY return this error code to reject secondary calls.
Caller SHOULD ensure that there are no other calls pending for the specified replication_source, and then retry with exponential back off.
Not authenticated
16 UNAUTHENTICATED
The invoked RPC does not carry secrets that are valid for authentication.
Caller SHALL either fix the secrets provided in the RPC, or otherwise regalvanize said secrets such that they will pass authentication by the Plugin for the attempted RPC, after which point the caller MAY retry the attempted RPC.
Error is Unknown
2 UNKNOWN
Indicates that a unknown error is generated
Caller MUST study the logs before retrying
PromoteVolume
// PromoteVolumeRequest holds the required information to promote volume as a// primary on local cluster.messagePromoteVolumeRequest {
// Deprecated "volume_id".reserved1;
reserved"volume_id";
// This field is optional.// Default value is false, force option to Promote the volume.boolforce=2;
// Plugin specific parameters passed in as opaque key-value pairs.map<string, string> parameters=3;
// Secrets required by the plugin to complete the request.map<string, string> secrets=4 [(csi.v1.csi_secret) = true];
// This field is OPTIONAL.// This field MUST contain enough information to uniquely identify// this specific replication// vs all other replications supported by this plugin.stringreplication_id=5 [(alpha_field) = true];
// If specified, this field will contain volume or volume group id// for replication.ReplicationSourcereplication_source=6;
}
// PromoteVolumeResponse holds the information to send when// volume is successfully promoted.messagePromoteVolumeResponse{
}
Error Scheme
Condition
gRPC Code
Description
Recovery Behavior
Missing required field
3 INVALID_ARGUMENT
Indicates that a required field is missing from the request.
Caller MUST fix the request by adding the missing required field before retrying.
Replication Source does not exist
5 NOT_FOUND
Indicates that the specified source does not exist.
Caller MUST verify that the replication_source is correct, the source is accessible, and has not been deleted before retrying with exponential back off.
Replication Source is not replicated
9 FAILED_PRECONDITION
Indicates that the Source corresponding to the specified replication_source could not be promoted due to failed precondition (for example replication is not enabled or Source cannot be promoted without force option).
Caller SHOULD ensure that replication is enabled.
Operation pending for Replication Source
10 ABORTED
Indicates that there is already an operation pending for the specified replication_source. In general the Cluster Orchestrator (CO) is responsible for ensuring that there is no more than one call "in-flight" per replication_source at a given time. However, in some circumstances, the CO MAY lose state (for example when the CO crashes and restarts), and MAY issue multiple calls simultaneously for the same replication_source. The Plugin, SHOULD handle this as gracefully as possible, and MAY return this error code to reject secondary calls.
Caller SHOULD ensure that there are no other calls pending for the specified replication_source, and then retry with exponential back off.
Call not implemented
12 UNIMPLEMENTED
The invoked RPC is not implemented by the Plugin or disabled in the Plugin's current mode of operation.
Caller MUST NOT retry.
Not authenticated
16 UNAUTHENTICATED
The invoked RPC does not carry secrets that are valid for authentication.
Caller SHALL either fix the secrets provided in the RPC, or otherwise regalvanize said secrets such that they will pass authentication by the Plugin for the attempted RPC, after which point the caller MAY retry the attempted RPC.
Error is Unknown
2 UNKNOWN
Indicates that a unknown error is generated
Caller MUST study the logs before retrying
DemoteVolume
// DemoteVolumeRequest holds the required information to demote volume on local// cluster.messageDemoteVolumeRequest {
// Deprecated "volume_id".reserved1;
reserved"volume_id";
// This field is optional.// Default value is false, force option to Demote the volume.boolforce=2;
// Plugin specific parameters passed in as opaque key-value pairs.map<string, string> parameters=3;
// Secrets required by the plugin to complete the request.map<string, string> secrets=4 [(csi.v1.csi_secret) = true];
// This field is OPTIONAL.// This field MUST contain enough information to uniquely identify// this specific replication// vs all other replications supported by this plugin.stringreplication_id=5 [(alpha_field) = true];
// If specified, this field will contain volume or volume group id// for replication.ReplicationSourcereplication_source=6;
}
// DemoteVolumeResponse holds the information to send when// volume is successfully demoted.messageDemoteVolumeResponse{
}
Error Scheme
Condition
gRPC Code
Description
Recovery Behavior
Missing required field
3 INVALID_ARGUMENT
Indicates that a required field is missing from the request.
Caller MUST fix the request by adding the missing required field before retrying.
Replication Source does not exist
5 NOT_FOUND
Indicates that the specified source does not exist.
Caller MUST verify that the replication_source is correct, the source is accessible, and has not been deleted before retrying with exponential back off.
Replication Source in not replicated
9 FAILED_PRECONDITION
Indicates that the Replication Source corresponding to the specified replication_source could not be demoted due to failed precondition (for example replication is not enabled).
Caller SHOULD ensure that replication is enabled.
Operation pending for Replication Source
10 ABORTED
Indicates that there is already an operation pending for the specified replication_source. In general the Cluster Orchestrator (CO) is responsible for ensuring that there is no more than one call "in-flight" per replication_source at a given time. However, in some circumstances, the CO MAY lose state (for example when the CO crashes and restarts), and MAY issue multiple calls simultaneously for the same replication_source. The Plugin, SHOULD handle this as gracefully as possible, and MAY return this error code to reject secondary calls.
Caller SHOULD ensure that there are no other calls pending for the specified replication_source, and then retry with exponential back off.
Call not implemented
12 UNIMPLEMENTED
The invoked RPC is not implemented by the Plugin or disabled in the Plugin's current mode of operation.
Caller MUST NOT retry.
Not authenticated
16 UNAUTHENTICATED
The invoked RPC does not carry secrets that are valid for authentication.
Caller SHALL either fix the secrets provided in the RPC, or otherwise regalvanize said secrets such that they will pass authentication by the Plugin for the attempted RPC, after which point the caller MAY retry the attempted RPC.
Error is Unknown
2 UNKNOWN
Indicates that a unknown error is generated
Caller MUST study the logs before retrying
ResyncVolume
// ResyncVolumeRequest holds the required information to resync volume.messageResyncVolumeRequest {
// Deprecated "volume_id".reserved1;
reserved"volume_id";
// This field is optional.// Default value is false, force option to Resync the volume.boolforce=2;
// Plugin specific parameters passed in as opaque key-value pairs.map<string, string> parameters=3;
// Secrets required by the plugin to complete the request.map<string, string> secrets=4 [(csi.v1.csi_secret) = true];
// This field is OPTIONAL.// This field MUST contain enough information to uniquely identify// this specific replication// vs all other replications supported by this plugin.stringreplication_id=5 [(alpha_field) = true];
// If specified, this field will contain volume or volume group id// for replication.ReplicationSourcereplication_source=6;
}
// ResyncVolumeResponse holds the information to send when// volume is successfully resynced.messageResyncVolumeResponse{
// Indicates that the volume is ready to use.// The default value is false.// This field is REQUIRED.boolready=1;
}
Error Scheme
Condition
gRPC Code
Description
Recovery Behavior
Missing required field
3 INVALID_ARGUMENT
Indicates that a required field is missing from the request.
Caller MUST fix the request by adding the missing required field before retrying.
Replication Source does not exist
5 NOT_FOUND
Indicates that the specified source does not exist.
Caller MUST verify that the replication_source is correct, the source is accessible, and has not been deleted before retrying with exponential back off.
Replication Source is not replicated or Replication Source is not demoted
9 FAILED_PRECONDITION
Indicates that the replication_source could not be resynced due to failed precondition (for example replication is not enabled on replication_source or thereplication_source is not in the demoted state).
Caller SHOULD ensure that Replication is enabled and the Replication Source is demoted.
Operation pending for Replication Source
10 ABORTED
Indicates that there is already an operation pending for the specified replication_source. In general the Cluster Orchestrator (CO) is responsible for ensuring that there is no more than one call "in-flight" per replication_source at a given time. However, in some circumstances, the CO MAY lose state (for example when the CO crashes and restarts), and MAY issue multiple calls simultaneously for the same replication_source. The Plugin, SHOULD handle this as gracefully as possible, and MAY return this error code to reject secondary calls.
Caller SHOULD ensure that there are no other calls pending for the specified replication_source, and then retry with exponential back off.
Call not implemented
12 UNIMPLEMENTED
The invoked RPC is not implemented by the Plugin or disabled in the Plugin's current mode of operation.
Caller MUST NOT retry.
Not authenticated
16 UNAUTHENTICATED
The invoked RPC does not carry secrets that are valid for authentication.
Caller SHALL either fix the secrets provided in the RPC, or otherwise regalvanize said secrets such that they will pass authentication by the Plugin for the attempted RPC, after which point the caller MAY retry the attempted RPC.
Error is Unknown
2 UNKNOWN
Indicates that a unknown error is generated
Caller MUST study the logs before retrying
GetVolumeReplicationInfo
// GetVolumeReplicationInfoRequest holds the required information to get// the Volume replication information.messageGetVolumeReplicationInfoRequest {
// Deprecated "volume_id".reserved1;
reserved"volume_id";
// Secrets required by the plugin to complete the request.map<string, string> secrets=2 [(csi.v1.csi_secret) = true];
// This field is OPTIONAL.// This field MUST contain enough information to uniquely identify// this specific replication// vs all other replications supported by this plugin.stringreplication_id=3 [(alpha_field) = true];
// If specified, this field will contain volume or volume group id// for replication.ReplicationSourcereplication_source=4;
}
// GetVolumeReplicationInfoResponse holds the information to send the// volume replication information.messageGetVolumeReplicationInfoResponse {
// Holds the last sync time.// This field is REQUIRED..google.protobuf.Timestamplast_sync_time=1;
// Holds the last sync duration.// last_sync_duration states the time taken to sync// to execute the last sync operation.// This field is OPTIONAL..google.protobuf.Durationlast_sync_duration=2;
// Holds the last sync bytes.// Represents number of bytes transferred// with the last synchronization.// This field is OPTIONAL.// The value of this field MUST NOT be negative.int64last_sync_bytes=3;
// Represents the type of replication status that can be returned// by a storage vendor.enumStatus {
// UNKNOWN indicates that the SP does not know the current// replication status.UNKNOWN=0;
// HEALTHY indicates that the replication is working properly.HEALTHY=1;
// DEGRADED indicates that the replication has stopped working// and it may require user intervention.DEGRADED=2;
// ERROR indicates that there is an error in replication// and it may require user intervention.ERROR=3;
}
// Represents the current replication status as reported by// the backend storage system.// This field is REQUIRED.Statusstatus=4;
// Contains a human readable message that describes the current// state of replication// This field is OPTIONAL.stringstatus_message=5;
}
Error Scheme
Condition
gRPC Code
Description
Recovery Behavior
Missing required field
3 INVALID_ARGUMENT
Indicates that a required field is missing from the request.
Caller MUST fix the request by adding the missing required field before retrying.
Replication Source does not exist or details not found
5 NOT_FOUND
Indicates that a Replication Source does not exist or details of replication_source are not avaiable at the moment.
Caller MUST verify that the replication_source is correct and that the replication_source is accessible and has not been deleted before retrying with exponential back off.
Replication Source is not replicated or not promoted
9 FAILED_PRECONDITION
Indicates that the replication information corresponding to the specified replication_source could not retrived due to failed precondition (for example replication is not enabled or not in the primary state).
Caller SHOULD ensure that replication is enabled on the replication_source and it is promoted.
Operation pending for Replication Source
10 ABORTED
Indicates that there is already an operation pending for the specified replication_source. In general the Cluster Orchestrator (CO) is responsible for ensuring that there is no more than one call "in-flight" per replication_source at a given time. However, in some circumstances, the CO MAY lose state (for example when the CO crashes and restarts), and MAY issue multiple calls simultaneously for the same replication_source. The Plugin, SHOULD handle this as gracefully as possible, and MAY return this error code to reject secondary calls.
Caller SHOULD ensure that there are no other calls pending for the specified replication_source, and then retry with exponential back off.
Call not implemented
12 UNIMPLEMENTED
The invoked RPC is not implemented by the Plugin or disabled in the Plugin's current mode of operation.
Caller MUST NOT retry.
Not authenticated
16 UNAUTHENTICATED
The invoked RPC does not carry secrets that are valid for authentication.
Caller SHALL either fix the secrets provided in the RPC, or otherwise regalvanize said secrets such that they will pass authentication by the Plugin for the attempted RPC, after which point the caller MAY retry the attempted RPC.
Error is Unknown
2 UNKNOWN
Indicates that a unknown error is generated
Caller MUST study the logs before retrying
GetReplicationDestinationInfo
// GetReplicationDestinationInfoRequest holds the required information to// get the destination volume or volume group details for an existing// replication.messageGetReplicationDestinationInfoRequest {
// Secrets required by the plugin to complete the request.map<string, string> secrets=1 [(csi.v1.csi_secret) = true];
// The source volume or volume group for which destination// details are requested.// This field is REQUIRED.ReplicationSourcereplication_source=2;
}
// GetReplicationDestinationInfoResponse holds the destination volume// or volume group details for an existing replication.messageGetReplicationDestinationInfoResponse {
// The destination details for the replication.// This field is REQUIRED.ReplicationDestinationreplication_destination=1;
}
// Specifies the destination details for a replication. One of the// type fields MUST be specified.messageReplicationDestination {
// VolumeDestination contains the destination details for a// replicated volume.messageVolumeDestination {
// The destination volume ID on the remote/target cluster.// This field is REQUIRED.stringvolume_id=1;
}
// VolumeGroupDestination contains the destination details for a// replicated volume group.messageVolumeGroupDestination {
// The destination volume group ID on the remote/target cluster.// This field is REQUIRED.stringvolume_group_id=1;
// Mapping of source volume IDs to their corresponding// destination volume IDs. Key is source volume_id,// value is destination volume_id.// This field is OPTIONAL.// This map reflects the current group membership at the// time of the call, accounting for dynamic group changes.// When provided, this map MUST be complete — it MUST// contain an entry for every volume currently in the group.// If the SP cannot determine the destination ID for all// volumes (e.g., newly added volumes have not finished// initial sync), the SP MUST return an error instead of// a partial map.map<string, string> volume_ids=2;
}
oneoftype {
// Volume destination typeVolumeDestinationvolume=1;
// Volume group destination typeVolumeGroupDestinationvolumegroup=2;
}
}
Error Scheme
Condition
gRPC Code
Description
Recovery Behavior
Missing required field
3 INVALID_ARGUMENT
A required field is missing from the request.
Caller MUST fix the request by adding the missing required field before retrying.
Replication Source does not exist
5 NOT_FOUND
The specified source does not exist.
Caller MUST verify that the replication_source is correct and accessible before retrying with exponential back off.
Replication Source is not replicated
9 FAILED_PRECONDITION
Destination information could not be retrieved because replication is not enabled.
Caller SHOULD ensure that replication is enabled on the replication_source.
Destination info not yet available
14 UNAVAILABLE
Destination details are not yet available. The SP needs time after replication.
Caller SHOULD retry with exponential back off. This is transient and resolves once replication is fully established.
Operation pending for Replication Source
10 ABORTED
There is already an operation pending for the specified replication_source.
Caller SHOULD ensure no other calls are pending for the replication_source, then retry with exponential back off.
Call not implemented
12 UNIMPLEMENTED
The invoked RPC is not implemented by the Plugin.
Caller MUST NOT retry.
Not authenticated
16 UNAUTHENTICATED
The invoked RPC does not carry valid secrets for authentication.
Caller SHALL fix or regenerate the secrets, then retry.
Error is Unknown
2 UNKNOWN
An unknown error occurred.
Caller MUST study the logs before retrying.
ReplicationSource
// Specifies what source the replication will be created from. One of the// type fields MUST be specified.messageReplicationSource {
// VolumeSource contains the details about the volume to be replicationmessageVolumeSource {
// Contains identity information for the existing volume.// This field is REQUIRED.stringvolume_id=1;
}
// VolumeGroupSource contains the details about// the volume group to be replicationmessageVolumeGroupSource {
// Contains identity information for the existing volume group.// This field is REQUIRED.stringvolume_group_id=1;
}
oneoftype {
// Volume source typeVolumeSourcevolume=1;
// Volume group source typeVolumeGroupSourcevolumegroup=2;
}
}