mirror of
https://github.com/kubernetes-csi/csi-driver-nvmf.git
synced 2025-06-28 15:36:50 +00:00
feat: add CreateVolume()
and DeleteVolume()
skeletons with RBAC permissions
Signed-off-by: cheolho.kang <cheolho.kang@samsung.com>
This commit is contained in:
parent
66a94e5fc3
commit
f70aef31d7
@ -42,6 +42,17 @@ rules:
|
|||||||
- apiGroups: [""]
|
- apiGroups: [""]
|
||||||
resources: ["secrets"]
|
resources: ["secrets"]
|
||||||
verbs: ["get", "list"]
|
verbs: ["get", "list"]
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: ClusterRole
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
metadata:
|
||||||
|
name: nvmf-external-provisioner-role
|
||||||
|
rules:
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["events"]
|
||||||
|
verbs: ["create", "update", "patch"]
|
||||||
|
|
||||||
---
|
---
|
||||||
kind: ClusterRoleBinding
|
kind: ClusterRoleBinding
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
@ -64,7 +75,10 @@ metadata:
|
|||||||
rules:
|
rules:
|
||||||
- apiGroups: [""]
|
- apiGroups: [""]
|
||||||
resources: ["persistentvolumes"]
|
resources: ["persistentvolumes"]
|
||||||
verbs: ["get", "list", "watch", "update", "patch"]
|
verbs: ["get", "list", "watch", "create", "delete", "update", "patch"]
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["persistentvolumeclaims"]
|
||||||
|
verbs: ["get", "list", "watch", "create", "delete", "update", "patch"]
|
||||||
- apiGroups: ["storage.k8s.io"]
|
- apiGroups: ["storage.k8s.io"]
|
||||||
resources: ["csinodes"]
|
resources: ["csinodes"]
|
||||||
verbs: ["get", "list", "watch"]
|
verbs: ["get", "list", "watch"]
|
||||||
@ -74,6 +88,9 @@ rules:
|
|||||||
- apiGroups: ["storage.k8s.io"]
|
- apiGroups: ["storage.k8s.io"]
|
||||||
resources: ["volumeattachments/status"]
|
resources: ["volumeattachments/status"]
|
||||||
verbs: ["patch"]
|
verbs: ["patch"]
|
||||||
|
- apiGroups: ["storage.k8s.io"]
|
||||||
|
resources: ["storageclasses"]
|
||||||
|
verbs: ["get", "list", "watch"]
|
||||||
|
|
||||||
---
|
---
|
||||||
kind: ClusterRoleBinding
|
kind: ClusterRoleBinding
|
||||||
@ -88,3 +105,63 @@ roleRef:
|
|||||||
kind: ClusterRole
|
kind: ClusterRole
|
||||||
name: nvmf-external-attacher-role
|
name: nvmf-external-attacher-role
|
||||||
apiGroup: rbac.authorization.k8s.io
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: ClusterRole
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
metadata:
|
||||||
|
name: nvmf-csi-node-role
|
||||||
|
rules:
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["events"]
|
||||||
|
verbs: ["get", "list", "watch", "create", "update", "patch"]
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["persistentvolumes"]
|
||||||
|
verbs: ["get", "list", "watch"]
|
||||||
|
- apiGroups: ["storage.k8s.io"]
|
||||||
|
resources: ["volumeattachments"]
|
||||||
|
verbs: ["get", "list", "watch"]
|
||||||
|
- apiGroups: ["storage.k8s.io"]
|
||||||
|
resources: ["csinodes"]
|
||||||
|
verbs: ["get", "list", "watch", "update"]
|
||||||
|
- apiGroups: ["storage.k8s.io"]
|
||||||
|
resources: ["csinodeinfos"]
|
||||||
|
verbs: ["get", "list", "watch"]
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
metadata:
|
||||||
|
name: csi-nvmf-node-binding
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: csi-nvmf-node-sa
|
||||||
|
namespace: kube-system
|
||||||
|
roleRef:
|
||||||
|
kind: ClusterRole
|
||||||
|
name: nvmf-csi-node-role
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
metadata:
|
||||||
|
name: csi-nvmf-node-volumeattachment-binding
|
||||||
|
subjects:
|
||||||
|
- kind: Group
|
||||||
|
name: system:nodes
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
roleRef:
|
||||||
|
kind: ClusterRole
|
||||||
|
name: nvmf-csi-node-volumeattachment-role
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: ClusterRole
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
metadata:
|
||||||
|
name: nvmf-csi-node-volumeattachment-role
|
||||||
|
rules:
|
||||||
|
- apiGroups: ["storage.k8s.io"]
|
||||||
|
resources: ["volumeattachments"]
|
||||||
|
verbs: ["get", "list", "watch"]
|
@ -17,8 +17,9 @@ limitations under the License.
|
|||||||
package nvmf
|
package nvmf
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"github.com/container-storage-interface/spec/lib/go/csi"
|
"github.com/container-storage-interface/spec/lib/go/csi"
|
||||||
"golang.org/x/net/context"
|
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
@ -35,13 +36,32 @@ func NewControllerServer(d *driver) *ControllerServer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// You should realize your volume provider here, such as requesting the Cloud to create an NVMf block and
|
// CreateVolume provisions a new volume
|
||||||
// returning specific information to you
|
|
||||||
func (c *ControllerServer) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) (*csi.CreateVolumeResponse, error) {
|
func (c *ControllerServer) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) (*csi.CreateVolumeResponse, error) {
|
||||||
|
volumeName := req.GetName()
|
||||||
|
if !isValidVolumeName(volumeName) {
|
||||||
|
return nil, status.Error(codes.InvalidArgument, "volume Name must be provided")
|
||||||
|
}
|
||||||
|
|
||||||
|
cap := req.GetVolumeCapabilities()
|
||||||
|
if !isValidVolumeCapabilities(cap) {
|
||||||
|
return nil, status.Error(codes.InvalidArgument, "volume Capabilities are invalid")
|
||||||
|
}
|
||||||
|
|
||||||
|
klog.V(4).Infof("CreateVolume called with name: %s", volumeName)
|
||||||
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "CreateVolume should implement by yourself. ")
|
return nil, status.Errorf(codes.Unimplemented, "CreateVolume should implement by yourself. ")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteVolume deletes a volume
|
||||||
func (c *ControllerServer) DeleteVolume(ctx context.Context, req *csi.DeleteVolumeRequest) (*csi.DeleteVolumeResponse, error) {
|
func (c *ControllerServer) DeleteVolume(ctx context.Context, req *csi.DeleteVolumeRequest) (*csi.DeleteVolumeResponse, error) {
|
||||||
|
volumeID := req.GetVolumeId()
|
||||||
|
if !isValidVolumeID(volumeID) {
|
||||||
|
return nil, status.Error(codes.InvalidArgument, "volume ID must be provided")
|
||||||
|
}
|
||||||
|
|
||||||
|
klog.V(4).Infof("DeleteVolume called for volume ID %s", volumeID)
|
||||||
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "DeleteVolume should implement by yourself. ")
|
return nil, status.Errorf(codes.Unimplemented, "DeleteVolume should implement by yourself. ")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,3 +112,41 @@ func (c *ControllerServer) DeleteSnapshot(ctx context.Context, request *csi.Dele
|
|||||||
func (c *ControllerServer) ListSnapshots(ctx context.Context, request *csi.ListSnapshotsRequest) (*csi.ListSnapshotsResponse, error) {
|
func (c *ControllerServer) ListSnapshots(ctx context.Context, request *csi.ListSnapshotsRequest) (*csi.ListSnapshotsResponse, error) {
|
||||||
return nil, status.Errorf(codes.Unimplemented, "ListSnapshots not implement")
|
return nil, status.Errorf(codes.Unimplemented, "ListSnapshots not implement")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isValidVolumeName(volumeName string) bool {
|
||||||
|
if volumeName == "" {
|
||||||
|
klog.Error("Volume Name cannot be empty")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func isValidVolumeID(volumeID string) bool {
|
||||||
|
if volumeID == "" {
|
||||||
|
klog.Error("Volume ID cannot be empty")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func isValidVolumeCapabilities(volCaps []*csi.VolumeCapability) bool {
|
||||||
|
if len(volCaps) == 0 {
|
||||||
|
klog.Error("Volume Capabilities not provided")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, cap := range volCaps {
|
||||||
|
if cap.GetBlock() != nil && cap.GetMount() != nil {
|
||||||
|
klog.Error("Cannot specify both block and mount access types")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if cap.GetBlock() == nil && cap.GetMount() == nil {
|
||||||
|
klog.Error("Must specify either block or mount access type")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
@ -57,7 +57,9 @@ func NewDriver(conf *GlobalConfig) *driver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *driver) Run(conf *GlobalConfig) {
|
func (d *driver) Run(conf *GlobalConfig) {
|
||||||
d.AddControllerServiceCapabilities([]csi.ControllerServiceCapability_RPC_Type{})
|
d.AddControllerServiceCapabilities([]csi.ControllerServiceCapability_RPC_Type{
|
||||||
|
csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME,
|
||||||
|
})
|
||||||
d.AddVolumeCapabilityAccessModes([]csi.VolumeCapability_AccessMode_Mode{
|
d.AddVolumeCapabilityAccessModes([]csi.VolumeCapability_AccessMode_Mode{
|
||||||
csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
|
csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user