Documentation ¶
Overview ¶
Package gocsi provides a Container Storage Interface (CSI) library, client, and other helpful utilities.
Index ¶
- Constants
- Variables
- func ChainUnaryClient(i ...grpc.UnaryClientInterceptor) grpc.UnaryClientInterceptor
- func ChainUnaryServer(i ...grpc.UnaryServerInterceptor) grpc.UnaryServerInterceptor
- func CompareVersions(a, b *csi.Version) int8
- func ErrVolumeNotFound(id string) error
- func FprintfVersion(w io.Writer, v csi.Version) (int, error)
- func GetCSIEndpoint() (network, addr string, err error)
- func GetCSIEndpointListener() (net.Listener, error)
- func GetRequestID(ctx context.Context) (uint64, bool)
- func IsSuccess(err error, successCodes ...codes.Code) error
- func IsSuccessfulResponse(method string, err error) error
- func LookupEnv(ctx context.Context, key string) (string, bool)
- func NewBlockCapability(mode csi.VolumeCapability_AccessMode_Mode) *csi.VolumeCapability
- func NewClientLogger(opts ...LoggingOption) grpc.UnaryClientInterceptor
- func NewClientRequestIDInjector() grpc.UnaryClientInterceptor
- func NewClientSpecValidator(opts ...SpecValidatorOption) grpc.UnaryClientInterceptor
- func NewIdempotentInterceptor(p IdempotencyProvider, opts ...IdempotentInterceptorOption) grpc.UnaryServerInterceptor
- func NewMountCapability(mode csi.VolumeCapability_AccessMode_Mode, fsType string, mountFlags ...string) *csi.VolumeCapability
- func NewServerLogger(opts ...LoggingOption) grpc.UnaryServerInterceptor
- func NewServerRequestIDInjector() grpc.UnaryServerInterceptor
- func NewServerSpecValidator(opts ...SpecValidatorOption) grpc.UnaryServerInterceptor
- func PageVolumes(ctx context.Context, client csi.ControllerClient, req csi.ListVolumesRequest, ...) (<-chan csi.VolumeInfo, <-chan error)
- func ParseMap(line string) map[string]string
- func ParseMapWS(line string) map[string]string
- func ParseProtoAddr(protoAddr string) (proto string, addr string, err error)
- func ParseSlice(line string) []string
- func ParseVersion(s string) (csi.Version, bool)
- func ParseVersions(s string) []csi.Version
- func Setenv(ctx context.Context, key, val string) error
- func SprintfVersion(v csi.Version) string
- func WithEnviron(ctx context.Context, v []string) context.Context
- func WithLookupEnv(ctx context.Context, f lookupEnvFunc) context.Context
- func WithSetenv(ctx context.Context, f setenvFunc) context.Context
- type IdempotencyProvider
- type IdempotentInterceptorOption
- type LoggingOption
- type MutexWithTryLock
- type PipeConn
- type SpecValidatorOption
- func WithRequiresControllerPublishVolumeCredentials() SpecValidatorOption
- func WithRequiresControllerUnpublishVolumeCredentials() SpecValidatorOption
- func WithRequiresCreateVolumeCredentials() SpecValidatorOption
- func WithRequiresDeleteVolumeCredentials() SpecValidatorOption
- func WithRequiresNodeID() SpecValidatorOption
- func WithRequiresNodePublishVolumeCredentials() SpecValidatorOption
- func WithRequiresNodeUnpublishVolumeCredentials() SpecValidatorOption
- func WithRequiresPublishVolumeInfo() SpecValidatorOption
- func WithRequiresVolumeAttributes() SpecValidatorOption
- func WithSuccessCreateVolumeAlreadyExists() SpecValidatorOption
- func WithSuccessDeleteVolumeNotFound() SpecValidatorOption
- func WithSupportedVersions(versions ...csi.Version) SpecValidatorOption
Constants ¶
const ( // Namespace is the namesapce used by the protobuf. Namespace = "csi" // CSIEndpoint is the name of the environment variable that // contains the CSI endpoint. CSIEndpoint = "CSI_ENDPOINT" // CreateVolume is the full method name for the // eponymous RPC message. CreateVolume = ctrlSvc + "CreateVolume" // DeleteVolume is the full method name for the // eponymous RPC message. DeleteVolume = ctrlSvc + "DeleteVolume" // ControllerPublishVolume is the full method name for the // eponymous RPC message. ControllerPublishVolume = ctrlSvc + "ControllerPublishVolume" // ControllerUnpublishVolume is the full method name for the // eponymous RPC message. ControllerUnpublishVolume = ctrlSvc + "ControllerUnpublishVolume" // ValidateVolumeCapabilities is the full method name for the // eponymous RPC message. ValidateVolumeCapabilities = ctrlSvc + "ValidateVolumeCapabilities" // ListVolumes is the full method name for the // eponymous RPC message. ListVolumes = ctrlSvc + "ListVolumes" // GetCapacity is the full method name for the // eponymous RPC message. GetCapacity = ctrlSvc + "GetCapacity" // ControllerGetCapabilities is the full method name for the // eponymous RPC message. ControllerGetCapabilities = ctrlSvc + "ControllerGetCapabilities" // ControllerProbe is the full method name for the // eponymous RPC message. ControllerProbe = ctrlSvc + "ControllerProbe" // GetSupportedVersions is the full method name for the // eponymous RPC message. GetSupportedVersions = identSvc + "GetSupportedVersions" // GetPluginInfo is the full method name for the // eponymous RPC message. GetPluginInfo = identSvc + "GetPluginInfo" // GetNodeID is the full method name for the // eponymous RPC message. GetNodeID = nodeSvc + "GetNodeID" // NodePublishVolume is the full method name for the // eponymous RPC message. NodePublishVolume = nodeSvc + "NodePublishVolume" // NodeUnpublishVolume is the full method name for the // eponymous RPC message. NodeUnpublishVolume = nodeSvc + "NodeUnpublishVolume" // NodeProbe is the full method name for the // eponymous RPC message. NodeProbe = nodeSvc + "NodeProbe" // NodeGetCapabilities is the full method name for the // eponymous RPC message. NodeGetCapabilities = nodeSvc + "NodeGetCapabilities" )
Variables ¶
var ErrAccessModeRequired = status.Error( codes.InvalidArgument, "acess mode required")
ErrAccessModeRequired occurs when an RPC is made with a missing acess mode argument.
var ErrAccessTypeRequired = status.Error( codes.InvalidArgument, "acess type required")
ErrAccessTypeRequired occurs when an RPC is made with a missing acess type argument.
var ErrBlockTypeRequired = status.Error( codes.InvalidArgument, "block type required")
ErrBlockTypeRequired occurs when an RPC is made with a missing access type block value.
var ErrEmptyNodeID = status.Error(codes.Internal, "empty node ID")
ErrEmptyNodeID occurs when an RPC returns an empty NodeID.
var ErrEmptyPluginName = status.Error( codes.Internal, "empty plug-in name")
ErrEmptyPluginName occurs when GetPluginInfo returns an empty plug-in name.
var ErrEmptyPublishVolumeInfo = status.Error( codes.Internal, "empty publish volume info")
ErrEmptyPublishVolumeInfo occurs when an RPC returns empty publish volume info.
var ErrEmptySupportedVersions = status.Error( codes.Internal, "empty supported versions")
ErrEmptySupportedVersions occurs when an RPC returns a zero-length supported versions list.
var ErrEmptyVendorVersion = status.Error( codes.Internal, "empty vendor version")
ErrEmptyVendorVersion occurs when GetPluginInfo returns an empty vendor version.
var ErrEmptyVolumeID = status.Error( codes.Internal, "empty volumeInfo.Id")
ErrEmptyVolumeID occurs when an RPC returns a VolumeInfo with an zero-length Id field.
var ErrInvalidProvider = errors.New("invalid service provider")
ErrInvalidProvider is returned from NewService if the specified provider name is unknown.
var ErrInvalidTargetPath = errors.New("invalid targetPath")
ErrInvalidTargetPath occurs when an RPC is made with an invalid targetPath argument.
var ErrMissingCSIEndpoint = errors.New("missing CSI_ENDPOINT")
ErrMissingCSIEndpoint occurs when the value for the environment variable CSI_ENDPOINT is not set.
var ErrMountTypeRequired = status.Error( codes.InvalidArgument, "mount type required")
ErrMountTypeRequired occurs when an RPC is made with a missing access type mount value.
var ErrNilVolumeInfo = status.Error( codes.Internal, "nil volumeInfo")
ErrNilVolumeInfo occurs when an RPC returns a nil VolumeInfo.
var ErrNodeIDRequired = status.Error( codes.InvalidArgument, "node ID required")
ErrNodeIDRequired occurs when an RPC is made with an empty node ID argument.
var ErrNonNilControllerCapabilities = status.Error( codes.Internal, "non-nil, empty controller capabilities")
ErrNonNilControllerCapabilities occurs when NodeGetCapabilities returns a non-nil, empty list.
var ErrNonNilEmptyAttribs = status.Error( codes.Internal, "non-nil, empty volumeInfo.Attributes")
ErrNonNilEmptyAttribs occurs when an RPC returns a VolumeInfo with a non-nil Attributes field that has no elements.
var ErrNonNilEmptyPluginManifest = status.Error( codes.Internal, "non-nil, empty plug-in manifest")
ErrNonNilEmptyPluginManifest occurs when GetPluginInfo returns a non-nil, empty manifest.
var ErrNonNilNodeCapabilities = status.Error( codes.Internal, "non-nil, empty node capabilities")
ErrNonNilNodeCapabilities occurs when NodeGetCapabilities returns a non-nil, empty list.
var ErrOpPending = status.Error( codes.FailedPrecondition, "op pending")
ErrOpPending occurs when an RPC is made against a resource that is involved in a concurrent operation.
var ErrParseProtoAddrRequired = errors.New(
"non-empty network address is required")
ErrParseProtoAddrRequired occurs when an empty string is provided to ParseProtoAddr.
var ErrPublishVolumeInfoRequired = status.Error( codes.InvalidArgument, "publish volume info required")
ErrPublishVolumeInfoRequired occurs when an RPC is made with an empty publish volume info argument.
var ErrTargetPathRequired = status.Error( codes.InvalidArgument, "target path required")
ErrTargetPathRequired occurs when an RPC is made with an empty target path argument.
var ErrUserCredentialsRequired = status.Error( codes.InvalidArgument, "user credentials required")
ErrUserCredentialsRequired occurs when an RPC is made with an empty user credentials argument.
var ErrVolumeAttributesRequired = status.Error( codes.InvalidArgument, "volume attributes required")
ErrVolumeAttributesRequired occurs when an RPC is made with an empty volume attributes argument.
var ErrVolumeCapabilitiesRequired = status.Error( codes.InvalidArgument, "volume capabilities required")
ErrVolumeCapabilitiesRequired occurs when an RPC is made with an empty volume capabilties argument.
var ErrVolumeCapabilityRequired = status.Error( codes.InvalidArgument, "volume capability required")
ErrVolumeCapabilityRequired occurs when an RPC is made with a missing volume capability argument.
var ErrVolumeIDRequired = status.Error( codes.InvalidArgument, "volume ID required")
ErrVolumeIDRequired occurs when an RPC is made with an empty volume ID argument.
var ErrVolumeNameRequired = status.Error( codes.InvalidArgument, "volume name required")
ErrVolumeNameRequired occurs when an RPC is made with an empty volume name argument.
Functions ¶
func ChainUnaryClient ¶
func ChainUnaryClient( i ...grpc.UnaryClientInterceptor) grpc.UnaryClientInterceptor
ChainUnaryClient chains one or more unary, client interceptors together into a left-to-right series that can be provided to a new gRPC client.
func ChainUnaryServer ¶
func ChainUnaryServer( i ...grpc.UnaryServerInterceptor) grpc.UnaryServerInterceptor
ChainUnaryServer chains one or more unary, server interceptors together into a left-to-right series that can be provided to a new gRPC server.
func CompareVersions ¶
CompareVersions compares two versions and returns:
-1 if a > b 0 if a = b 1 if a < b
func ErrVolumeNotFound ¶ added in v0.2.4
ErrVolumeNotFound returns an error indicating a volume with the specified ID cannot be found.
func FprintfVersion ¶ added in v0.2.0
FprintfVersion formats a Version as a string to the specified writer.
func GetCSIEndpoint ¶
GetCSIEndpoint returns the network address specified by the environment variable CSI_ENDPOINT.
func GetCSIEndpointListener ¶
GetCSIEndpointListener returns the net.Listener for the endpoint specified by the environment variable CSI_ENDPOINT.
func GetRequestID ¶
GetRequestID inspects the context for gRPC metadata and returns its request ID if available.
func IsSuccess ¶ added in v0.2.0
IsSuccess returns nil if the provided error is an RPC error with an error code that is OK (0) or matches one of the additional, provided successful error codes. Otherwise the original error is returned.
func IsSuccessfulResponse ¶ added in v0.2.0
IsSuccessfulResponse uses IsSuccess to determine if the response for a specific CSI method is successful. If successful a nil value is returned; otherwise the original error is returned.
func LookupEnv ¶ added in v0.2.0
LookupEnv returns the value of the provided environment variable by:
Inspecting the context for a key "os.Environ" with a string slice value. If such a key and value exist then the string slice is searched for the specified key and if found its value is returned.
Inspecting the context for a key "os.LookupEnv" with a value of func(string) (string, bool). If such a key and value exist then the function is used to attempt to discover the key's value. If the key and value are found they are returned.
Returning the result of os.LookupEnv.
func NewBlockCapability ¶
func NewBlockCapability( mode csi.VolumeCapability_AccessMode_Mode) *csi.VolumeCapability
NewBlockCapability returns a new *csi.VolumeCapability for a volume that is to be accessed as a raw device.
func NewClientLogger ¶ added in v0.2.0
func NewClientLogger( opts ...LoggingOption) grpc.UnaryClientInterceptor
NewClientLogger provides a UnaryClientInterceptor that can be configured to log both request and response data.
func NewClientRequestIDInjector ¶ added in v0.2.0
func NewClientRequestIDInjector() grpc.UnaryClientInterceptor
NewClientRequestIDInjector provides a UnaryClientInterceptor that injects the outgoing context with gRPC metadata that contains a unique ID.
func NewClientSpecValidator ¶ added in v0.2.0
func NewClientSpecValidator( opts ...SpecValidatorOption) grpc.UnaryClientInterceptor
NewClientSpecValidator provides a UnaryClientInterceptor that validates client request and response data against the CSI specification.
func NewIdempotentInterceptor ¶
func NewIdempotentInterceptor( p IdempotencyProvider, opts ...IdempotentInterceptorOption) grpc.UnaryServerInterceptor
NewIdempotentInterceptor returns a new server-side, gRPC interceptor that can be used in conjunction with an IdempotencyProvider to provide serialized, idempotent access to the following CSI RPCs:
- CreateVolume
- DeleteVolume
- ControllerPublishVolume
- ControllerUnpublishVolume
- NodePublishVolume
- NodeUnpublishVolume
func NewMountCapability ¶
func NewMountCapability( mode csi.VolumeCapability_AccessMode_Mode, fsType string, mountFlags ...string) *csi.VolumeCapability
NewMountCapability returns a new *csi.VolumeCapability for a volume that is to be mounted.
func NewServerLogger ¶ added in v0.2.0
func NewServerLogger( opts ...LoggingOption) grpc.UnaryServerInterceptor
NewServerLogger returns a new UnaryServerInterceptor that can be configured to log both request and response data.
func NewServerRequestIDInjector ¶ added in v0.2.0
func NewServerRequestIDInjector() grpc.UnaryServerInterceptor
NewServerRequestIDInjector returns a new UnaryServerInterceptor that reads a unique request ID from the incoming context's gRPC metadata. If the incoming context does not contain gRPC metadata or a request ID, then a new request ID is generated.
func NewServerSpecValidator ¶ added in v0.2.0
func NewServerSpecValidator( opts ...SpecValidatorOption) grpc.UnaryServerInterceptor
NewServerSpecValidator returns a new UnaryServerInterceptor that validates server request and response data against the CSI specification.
func PageVolumes ¶ added in v0.2.0
func PageVolumes( ctx context.Context, client csi.ControllerClient, req csi.ListVolumesRequest, opts ...grpc.CallOption) (<-chan csi.VolumeInfo, <-chan error)
PageVolumes issues one or more ListVolumes requests to retrieve all available volumes, returning them over a Go channel.
func ParseMap ¶ added in v0.2.0
ParseMap parses a string into a map. The string's expected pattern is:
KEY1=VAL1, "KEY2=VAL2 ", "KEY 3= VAL3"
The key/value pairs are separated by a comma and optional whitespace. Please see the encoding/csv package (https://goo.gl/1j1xb9) for information on how to quote keys and/or values to include leading and trailing whitespace.
func ParseMapWS ¶ added in v0.2.4
ParseMapWS parses a string into a map. The string's expected pattern is:
KEY1=VAL1 KEY2="VAL2 " "KEY 3"=' VAL3'
The key/value pairs are separated by one or more whitespace characters. Keys and/or values with whitespace should be quoted with either single or double quotes.
func ParseProtoAddr ¶
ParseProtoAddr parses a Golang network address.
func ParseSlice ¶ added in v0.2.4
ParseSlice parses a string into a slice. The string's expected pattern is:
VAL1, "VAL2 ", " VAL3 "
The values are separated by a comma and optional whitespace. Please see the encoding/csv package (https://goo.gl/1j1xb9) for information on how to quote values to include leading and trailing whitespace.
func ParseVersion ¶
ParseVersion parses a string for a CSI version.
func ParseVersions ¶ added in v0.2.0
ParseVersions parses a string for one or more CSI versions.
func Setenv ¶ added in v0.2.0
Setenv sets the value of the provided environment variable to the specified value by first inspecting the context for a key "os.Setenv" with a value of func(string, string) error. If the context does not contain such a function then os.Setenv is used instead.
func SprintfVersion ¶
SprintfVersion formats a Version as a string.
func WithEnviron ¶ added in v0.2.3
WithEnviron returns a new Context with the provided environment variable string slice.
func WithLookupEnv ¶ added in v0.2.0
WithLookupEnv returns a new Context with the provided function.
Types ¶
type IdempotencyProvider ¶
type IdempotencyProvider interface { // GetVolumeID should return the ID of the volume specified // by the provided volume name. If the volume does not exist then // an empty string should be returned. GetVolumeID(ctx context.Context, name string) (string, error) // GetVolumeInfo should return information about the volume // specified by the provided volume ID or name. If the volume does not // exist then a nil value should be returned. GetVolumeInfo(ctx context.Context, id, name string) (*csi.VolumeInfo, error) // IsControllerPublished should return publication for a volume's // publication status on a specified node. IsControllerPublished( ctx context.Context, volumeID, nodeID string) (map[string]string, error) // IsNodePublished should return a flag indicating whether or // not the volume exists and is published on the current host. IsNodePublished( ctx context.Context, id string, pubVolInfo map[string]string, targetPath string) (bool, error) }
IdempotencyProvider is the interface that works with a server-side, gRPC interceptor to provide serial access and idempotency for CSI's volume resources.
type IdempotentInterceptorOption ¶ added in v0.2.0
type IdempotentInterceptorOption func(*idempIntercOpts)
IdempotentInterceptorOption configures the idempotent interceptor.
func WithIdempRequireVolumeExists ¶ added in v0.2.0
func WithIdempRequireVolumeExists() IdempotentInterceptorOption
WithIdempRequireVolumeExists is an IdempotentInterceptorOption that enforces the requirement that volumes must exist before proceeding with an operation.
func WithIdempTimeout ¶ added in v0.2.0
func WithIdempTimeout(t time.Duration) IdempotentInterceptorOption
WithIdempTimeout is an IdempotentInterceptorOption that sets the timeout used by the idempotent interceptor.
type LoggingOption ¶ added in v0.2.0
type LoggingOption func(*loggingOpts)
LoggingOption configures the logging interceptor.
func WithRequestLogging ¶ added in v0.2.0
func WithRequestLogging(w io.Writer) LoggingOption
WithRequestLogging is a LoggingOption that enables request logging for the logging interceptor.
func WithResponseLogging ¶ added in v0.2.0
func WithResponseLogging(w io.Writer) LoggingOption
WithResponseLogging is a LoggingOption that enables response logging for the logging interceptor.
type MutexWithTryLock ¶
type MutexWithTryLock interface { // Lock locks the mutex. Lock() // Unlock unlocks the mutex. Unlock() // TryLock attempts to obtain a lock but times out if no lock // can be obtained in the specified duration. A flag is returned // indicating whether or not the lock was obtained. TryLock(timeout time.Duration) bool }
MutexWithTryLock is a lock object that implements the semantics of a sync.Mutex in addition to a TryLock function.
func NewMutexWithTryLock ¶
func NewMutexWithTryLock() MutexWithTryLock
NewMutexWithTryLock returns a new mutex that implements TryLock.
type PipeConn ¶ added in v0.2.0
type PipeConn interface { net.Listener // DialGrpc is used by a grpc client. DialGrpc(raddr string, timeout time.Duration) (net.Conn, error) // DialHTTP is used by net.http clients. DialHTTP(ctx context.Context, network, addr string) (net.Conn, error) }
PipeConn is an in-memory network connection that can be provided to a Serve function as a net.Listener and to gRPC/net.http clients as their dialer.
func NewPipeConn ¶ added in v0.2.0
NewPipeConn returns a new pipe connection. The provided name is returned by PipeConn.Addr().String().
type SpecValidatorOption ¶ added in v0.2.0
type SpecValidatorOption func(*specValidatorOpts)
SpecValidatorOption configures the spec validator interceptor.
func WithRequiresControllerPublishVolumeCredentials ¶ added in v0.2.0
func WithRequiresControllerPublishVolumeCredentials() SpecValidatorOption
WithRequiresControllerPublishVolumeCredentials is a SpecValidatorOption that indicates the eponymous requests must contain non-empty credentials data.
func WithRequiresControllerUnpublishVolumeCredentials ¶ added in v0.2.0
func WithRequiresControllerUnpublishVolumeCredentials() SpecValidatorOption
WithRequiresControllerUnpublishVolumeCredentials is a SpecValidatorOption that indicates the eponymous requests must contain non-empty credentials data.
func WithRequiresCreateVolumeCredentials ¶ added in v0.2.0
func WithRequiresCreateVolumeCredentials() SpecValidatorOption
WithRequiresCreateVolumeCredentials is a SpecValidatorOption that indicates the eponymous requests must contain non-empty credentials data.
func WithRequiresDeleteVolumeCredentials ¶ added in v0.2.0
func WithRequiresDeleteVolumeCredentials() SpecValidatorOption
WithRequiresDeleteVolumeCredentials is a SpecValidatorOption that indicates the eponymous requests must contain non-empty credentials data.
func WithRequiresNodeID ¶ added in v0.2.0
func WithRequiresNodeID() SpecValidatorOption
WithRequiresNodeID is a SpecValidatorOption that indicates ControllerPublishVolume requests and GetNodeID responses must contain non-empty node ID data.
func WithRequiresNodePublishVolumeCredentials ¶ added in v0.2.0
func WithRequiresNodePublishVolumeCredentials() SpecValidatorOption
WithRequiresNodePublishVolumeCredentials is a SpecValidatorOption that indicates the eponymous requests must contain non-empty credentials data.
func WithRequiresNodeUnpublishVolumeCredentials ¶ added in v0.2.0
func WithRequiresNodeUnpublishVolumeCredentials() SpecValidatorOption
WithRequiresNodeUnpublishVolumeCredentials is a SpecValidatorOption that indicates the eponymous requests must contain non-empty credentials data.
func WithRequiresPublishVolumeInfo ¶ added in v0.2.0
func WithRequiresPublishVolumeInfo() SpecValidatorOption
WithRequiresPublishVolumeInfo is a SpecValidatorOption that indicates ControllerPublishVolume responses and NodePublishVolume requests must contain non-empty publish volume info data.
func WithRequiresVolumeAttributes ¶ added in v0.2.0
func WithRequiresVolumeAttributes() SpecValidatorOption
WithRequiresVolumeAttributes is a SpecValidatorOption that indicates ControllerPublishVolume, ValidateVolumeCapabilities, and NodePublishVolume requests must contain non-empty volume attribute data.
func WithSuccessCreateVolumeAlreadyExists ¶ added in v0.2.0
func WithSuccessCreateVolumeAlreadyExists() SpecValidatorOption
WithSuccessCreateVolumeAlreadyExists is a SpecValidatorOption that the eponymous request should treat the eponymous error code as successful.
func WithSuccessDeleteVolumeNotFound ¶ added in v0.2.0
func WithSuccessDeleteVolumeNotFound() SpecValidatorOption
WithSuccessDeleteVolumeNotFound is a SpecValidatorOption that the eponymous request should treat the eponymous error code as successful.
func WithSupportedVersions ¶ added in v0.2.0
func WithSupportedVersions(versions ...csi.Version) SpecValidatorOption
WithSupportedVersions is a SpecValidatorOption that indicates the list of versions supported by any CSI RPC that participates in version validation.