feat: add CreateVolume() and DeleteVolume() skeletons with RBAC permissions

Signed-off-by: cheolho.kang <cheolho.kang@samsung.com>
This commit is contained in:
cheolho.kang 2025-03-19 14:53:05 +09:00
parent 66a94e5fc3
commit f70aef31d7
3 changed files with 143 additions and 6 deletions

View File

@ -42,6 +42,17 @@ rules:
- apiGroups: [""]
resources: ["secrets"]
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
apiVersion: rbac.authorization.k8s.io/v1
@ -64,7 +75,10 @@ metadata:
rules:
- apiGroups: [""]
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"]
resources: ["csinodes"]
verbs: ["get", "list", "watch"]
@ -74,6 +88,9 @@ rules:
- apiGroups: ["storage.k8s.io"]
resources: ["volumeattachments/status"]
verbs: ["patch"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
---
kind: ClusterRoleBinding
@ -87,4 +104,64 @@ subjects:
roleRef:
kind: ClusterRole
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"]

View File

@ -17,8 +17,9 @@ limitations under the License.
package nvmf
import (
"context"
"github.com/container-storage-interface/spec/lib/go/csi"
"golang.org/x/net/context"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"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
// returning specific information to you
// CreateVolume provisions a new volume
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. ")
}
// DeleteVolume deletes a volume
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. ")
}
@ -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) {
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
}

View File

@ -57,7 +57,9 @@ func NewDriver(conf *GlobalConfig) *driver {
}
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{
csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
})