/* Copyright 2024 p5x. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package csi import ( "context" "k8s.io/klog" "github.com/container-storage-interface/spec/lib/go/csi" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) var ( controllerCaps = []csi.ControllerServiceCapability_RPC_Type{ csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME, csi.ControllerServiceCapability_RPC_PUBLISH_UNPUBLISH_VOLUME, } ) type controllerService struct { p5x *p5xApi csi.UnimplementedControllerServer } var _ csi.ControllerServer = &controllerService{} func newControllerService(p5x *p5xApi) controllerService { return controllerService{ p5x: p5x, } } // CreateVolume creates a volume func (d *controllerService) CreateVolume(ctx context.Context, request *csi.CreateVolumeRequest) (*csi.CreateVolumeResponse, error) { klog.Infof("controller.CreateVolume: %s (size: %d)", request.Name, request.CapacityRange.GetRequiredBytes()) if len(request.Name) == 0 { return nil, status.Error(codes.InvalidArgument, "Volume Name cannot be empty") } if request.VolumeCapabilities == nil { return nil, status.Error(codes.InvalidArgument, "Volume Capabilities cannot be empty") } requiredCap := request.CapacityRange.GetRequiredBytes() vol, err := d.p5x.CreateVolume(request.Name, requiredCap) if err != nil { return nil, err } csiVol := csi.Volume{ VolumeId: vol.Name, CapacityBytes: vol.SizeInBytes, } klog.Info("controller.CreateVolume: Created volume: ", vol) return &csi.CreateVolumeResponse{Volume: &csiVol}, nil // volCtx := make(map[string]string) // for k, v := range request.Parameters { // volCtx[k] = v // } // // volCtx["subPath"] = request.Name // // volume := csi.Volume{ // VolumeId: request.Name, // CapacityBytes: requiredCap, // VolumeContext: volCtx, // } } // DeleteVolume deletes a volume func (d *controllerService) DeleteVolume(ctx context.Context, request *csi.DeleteVolumeRequest) (*csi.DeleteVolumeResponse, error) { klog.Infof("controller.DeleteVolume: %s", request.GetVolumeId()) vol, err := d.p5x.GetVolumeByName(request.GetVolumeId()) if err != nil { return nil, err } err = d.p5x.DeleteVolume(vol) if err != nil { return nil, err } klog.Info("controller.DeleteVolume: Successfully deleted volume: ", vol) return &csi.DeleteVolumeResponse{}, nil } // ControllerGetCapabilities get controller capabilities func (d *controllerService) ControllerGetCapabilities(ctx context.Context, request *csi.ControllerGetCapabilitiesRequest) (*csi.ControllerGetCapabilitiesResponse, error) { klog.Info("controller.ControllerGetCapabilities: called") var caps []*csi.ControllerServiceCapability for _, cap := range controllerCaps { c := &csi.ControllerServiceCapability{ Type: &csi.ControllerServiceCapability_Rpc{ Rpc: &csi.ControllerServiceCapability_RPC{ Type: cap, }, }, } caps = append(caps, c) } return &csi.ControllerGetCapabilitiesResponse{Capabilities: caps}, nil } // ControllerPublishVolume publish a volume func (d *controllerService) ControllerPublishVolume(ctx context.Context, request *csi.ControllerPublishVolumeRequest) (*csi.ControllerPublishVolumeResponse, error) { klog.Infof("controller.ControllerPublishVolume: %s on node %s", request.GetVolumeId(), request.GetNodeId()) return nil, status.Error(codes.Unimplemented, "controller.ControllerPublishVolume") } // ControllerUnpublishVolume unpublish a volume func (d *controllerService) ControllerUnpublishVolume(ctx context.Context, request *csi.ControllerUnpublishVolumeRequest) (*csi.ControllerUnpublishVolumeResponse, error) { klog.Infof("controller.ControllerUnpublishVolume: %s on node %s", request.GetVolumeId(), request.GetNodeId()) return nil, status.Error(codes.Unimplemented, "controller.ControllerUnpublishVolume") } // ValidateVolumeCapabilities validate volume capabilities func (d *controllerService) ValidateVolumeCapabilities(ctx context.Context, request *csi.ValidateVolumeCapabilitiesRequest) (*csi.ValidateVolumeCapabilitiesResponse, error) { klog.Infof("controller.ValidateVolumeCapabilities: %s", request.GetVolumeId()) return nil, status.Error(codes.Unimplemented, "controller.ValidateVolumeCapabilities") } // ListVolumes list volumes func (d *controllerService) ListVolumes(ctx context.Context, request *csi.ListVolumesRequest) (*csi.ListVolumesResponse, error) { klog.Infof("controller.ListVolumes: called") return nil, status.Error(codes.Unimplemented, "controller.ListVolumes") } // GetCapacity get capacity func (d *controllerService) GetCapacity(ctx context.Context, request *csi.GetCapacityRequest) (*csi.GetCapacityResponse, error) { klog.Infof("controller.GetCapacity: called") return nil, status.Error(codes.Unimplemented, "controller.GetCapacity") } // CreateSnapshot create a snapshot func (d *controllerService) CreateSnapshot(ctx context.Context, request *csi.CreateSnapshotRequest) (*csi.CreateSnapshotResponse, error) { klog.Infof("controller.CreateSnapshot: called") return nil, status.Error(codes.Unimplemented, "controller.CreateSnapshot") } // DeleteSnapshot delete a snapshot func (d *controllerService) DeleteSnapshot(ctx context.Context, request *csi.DeleteSnapshotRequest) (*csi.DeleteSnapshotResponse, error) { klog.Infof("controller.DeleteSnapshot: called") return nil, status.Error(codes.Unimplemented, "controller.DeleteSnapshot") } // ListSnapshots list snapshots func (d *controllerService) ListSnapshots(ctx context.Context, request *csi.ListSnapshotsRequest) (*csi.ListSnapshotsResponse, error) { klog.Infof("controller.ListSnapshots: called") return nil, status.Error(codes.Unimplemented, "controller.ListSnapshots") } // ControllerExpandVolume expand a volume func (d *controllerService) ControllerExpandVolume(ctx context.Context, request *csi.ControllerExpandVolumeRequest) (*csi.ControllerExpandVolumeResponse, error) { klog.Infof("controller.ControllerExpandVolume: %s (size: %d)", request.GetVolumeId(), request.GetCapacityRange().GetRequiredBytes()) return nil, status.Error(codes.Unimplemented, "controller.ControllerExpandVolume") } // ControllerGetVolume get a volume func (d *controllerService) ControllerGetVolume(ctx context.Context, request *csi.ControllerGetVolumeRequest) (*csi.ControllerGetVolumeResponse, error) { klog.Infof("controller.ControllerGetVolume: %s", request.GetVolumeId()) return nil, status.Error(codes.Unimplemented, "controller.ControllerGetVolume") } // ControllerModifyVolume modify a volume func (d *controllerService) ControllerModifyVolume(ctx context.Context, request *csi.ControllerModifyVolumeRequest) (*csi.ControllerModifyVolumeResponse, error) { klog.Infof("controller.ControllerModifyVolume: %s", request.GetVolumeId()) return nil, status.Error(codes.Unimplemented, "controller.ControllerModifyVolume") }