diff --git a/pkg/backend/aio.go b/pkg/backend/aio.go index 66409216..c30fe81a 100644 --- a/pkg/backend/aio.go +++ b/pkg/backend/aio.go @@ -20,7 +20,6 @@ import ( "go.einride.tech/aip/fieldbehavior" "go.einride.tech/aip/fieldmask" "go.einride.tech/aip/resourceid" - "go.einride.tech/aip/resourcename" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/emptypb" @@ -35,19 +34,14 @@ func sortAioVolumes(volumes []*pb.AioVolume) { // CreateAioVolume creates an Aio volume func (s *Server) CreateAioVolume(_ context.Context, in *pb.CreateAioVolumeRequest) (*pb.AioVolume, error) { log.Printf("CreateAioVolume: Received from client: %v", in) - // check required fields - if err := fieldbehavior.ValidateRequiredFields(in); err != nil { + // check input correctness + if err := s.validateCreateAioVolumeRequest(in); err != nil { log.Printf("error: %v", err) return nil, err } // see https://google.aip.dev/133#user-specified-ids resourceID := resourceid.NewSystemGenerated() if in.AioVolumeId != "" { - err := resourceid.ValidateUserSettable(in.AioVolumeId) - if err != nil { - log.Printf("error: %v", err) - return nil, err - } log.Printf("client provided the ID of a resource %v, ignoring the name field %v", in.AioVolumeId, in.AioVolume.Name) resourceID = in.AioVolumeId } @@ -85,13 +79,8 @@ func (s *Server) CreateAioVolume(_ context.Context, in *pb.CreateAioVolumeReques // DeleteAioVolume deletes an Aio volume func (s *Server) DeleteAioVolume(_ context.Context, in *pb.DeleteAioVolumeRequest) (*emptypb.Empty, error) { log.Printf("DeleteAioVolume: Received from client: %v", in) - // check required fields - if err := fieldbehavior.ValidateRequiredFields(in); err != nil { - log.Printf("error: %v", err) - return nil, err - } - // Validate that a resource name conforms to the restrictions outlined in AIP-122. - if err := resourcename.Validate(in.Name); err != nil { + // check input correctness + if err := s.validateDeleteAioVolumeRequest(in); err != nil { log.Printf("error: %v", err) return nil, err } @@ -128,13 +117,8 @@ func (s *Server) DeleteAioVolume(_ context.Context, in *pb.DeleteAioVolumeReques // UpdateAioVolume updates an Aio volume func (s *Server) UpdateAioVolume(_ context.Context, in *pb.UpdateAioVolumeRequest) (*pb.AioVolume, error) { log.Printf("UpdateAioVolume: Received from client: %v", in) - // check required fields - if err := fieldbehavior.ValidateRequiredFields(in); err != nil { - log.Printf("error: %v", err) - return nil, err - } - // Validate that a resource name conforms to the restrictions outlined in AIP-122. - if err := resourcename.Validate(in.AioVolume.Name); err != nil { + // check input correctness + if err := s.validateUpdateAioVolumeRequest(in); err != nil { log.Printf("error: %v", err) return nil, err } @@ -252,13 +236,8 @@ func (s *Server) ListAioVolumes(_ context.Context, in *pb.ListAioVolumesRequest) // GetAioVolume gets an Aio volume func (s *Server) GetAioVolume(_ context.Context, in *pb.GetAioVolumeRequest) (*pb.AioVolume, error) { log.Printf("GetAioVolume: Received from client: %v", in) - // check required fields - if err := fieldbehavior.ValidateRequiredFields(in); err != nil { - log.Printf("error: %v", err) - return nil, err - } - // Validate that a resource name conforms to the restrictions outlined in AIP-122. - if err := resourcename.Validate(in.Name); err != nil { + // check input correctness + if err := s.validateGetAioVolumeRequest(in); err != nil { log.Printf("error: %v", err) return nil, err } @@ -291,13 +270,8 @@ func (s *Server) GetAioVolume(_ context.Context, in *pb.GetAioVolumeRequest) (*p // StatsAioVolume gets an Aio volume stats func (s *Server) StatsAioVolume(_ context.Context, in *pb.StatsAioVolumeRequest) (*pb.StatsAioVolumeResponse, error) { log.Printf("StatsAioVolume: Received from client: %v", in) - // check required fields - if err := fieldbehavior.ValidateRequiredFields(in); err != nil { - log.Printf("error: %v", err) - return nil, err - } - // Validate that a resource name conforms to the restrictions outlined in AIP-122. - if err := resourcename.Validate(in.Name); err != nil { + // check input correctness + if err := s.validateStatsAioVolumeRequest(in); err != nil { log.Printf("error: %v", err) return nil, err } diff --git a/pkg/backend/aio_validate.go b/pkg/backend/aio_validate.go index 9d9737e3..2364b33d 100644 --- a/pkg/backend/aio_validate.go +++ b/pkg/backend/aio_validate.go @@ -3,3 +3,62 @@ // Package backend implememnts the BackEnd APIs (network facing) of the storage Server package backend + +import ( + "go.einride.tech/aip/fieldbehavior" + "go.einride.tech/aip/resourceid" + "go.einride.tech/aip/resourcename" + + pb "github.com/opiproject/opi-api/storage/v1alpha1/gen/go" +) + +func (s *Server) validateCreateAioVolumeRequest(in *pb.CreateAioVolumeRequest) error { + // check required fields + if err := fieldbehavior.ValidateRequiredFields(in); err != nil { + return err + } + // see https://google.aip.dev/133#user-specified-ids + if in.AioVolumeId != "" { + if err := resourceid.ValidateUserSettable(in.AioVolumeId); err != nil { + return err + } + } + // TODO: validate also: block_size, blocks_count, uuid, filename + return nil +} + +func (s *Server) validateDeleteAioVolumeRequest(in *pb.DeleteAioVolumeRequest) error { + // check required fields + if err := fieldbehavior.ValidateRequiredFields(in); err != nil { + return err + } + // Validate that a resource name conforms to the restrictions outlined in AIP-122. + return resourcename.Validate(in.Name) +} + +func (s *Server) validateUpdateAioVolumeRequest(in *pb.UpdateAioVolumeRequest) error { + // check required fields + if err := fieldbehavior.ValidateRequiredFields(in); err != nil { + return err + } + // Validate that a resource name conforms to the restrictions outlined in AIP-122. + return resourcename.Validate(in.AioVolume.Name) +} + +func (s *Server) validateGetAioVolumeRequest(in *pb.GetAioVolumeRequest) error { + // check required fields + if err := fieldbehavior.ValidateRequiredFields(in); err != nil { + return err + } + // Validate that a resource name conforms to the restrictions outlined in AIP-122. + return resourcename.Validate(in.Name) +} + +func (s *Server) validateStatsAioVolumeRequest(in *pb.StatsAioVolumeRequest) error { + // check required fields + if err := fieldbehavior.ValidateRequiredFields(in); err != nil { + return err + } + // Validate that a resource name conforms to the restrictions outlined in AIP-122. + return resourcename.Validate(in.Name) +} diff --git a/pkg/backend/null.go b/pkg/backend/null.go index 95c49b30..8eb6f783 100644 --- a/pkg/backend/null.go +++ b/pkg/backend/null.go @@ -21,7 +21,6 @@ import ( "go.einride.tech/aip/fieldbehavior" "go.einride.tech/aip/fieldmask" "go.einride.tech/aip/resourceid" - "go.einride.tech/aip/resourcename" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/emptypb" @@ -36,19 +35,14 @@ func sortNullVolumes(volumes []*pb.NullVolume) { // CreateNullVolume creates a Null volume instance func (s *Server) CreateNullVolume(_ context.Context, in *pb.CreateNullVolumeRequest) (*pb.NullVolume, error) { log.Printf("CreateNullVolume: Received from client: %v", in) - // check required fields - if err := fieldbehavior.ValidateRequiredFields(in); err != nil { + // check input correctness + if err := s.validateCreateNullVolumeRequest(in); err != nil { log.Printf("error: %v", err) return nil, err } // see https://google.aip.dev/133#user-specified-ids resourceID := resourceid.NewSystemGenerated() if in.NullVolumeId != "" { - err := resourceid.ValidateUserSettable(in.NullVolumeId) - if err != nil { - log.Printf("error: %v", err) - return nil, err - } log.Printf("client provided the ID of a resource %v, ignoring the name field %v", in.NullVolumeId, in.NullVolume.Name) resourceID = in.NullVolumeId } @@ -86,13 +80,8 @@ func (s *Server) CreateNullVolume(_ context.Context, in *pb.CreateNullVolumeRequ // DeleteNullVolume deletes a Null volume instance func (s *Server) DeleteNullVolume(_ context.Context, in *pb.DeleteNullVolumeRequest) (*emptypb.Empty, error) { log.Printf("DeleteNullVolume: Received from client: %v", in) - // check required fields - if err := fieldbehavior.ValidateRequiredFields(in); err != nil { - log.Printf("error: %v", err) - return nil, err - } - // Validate that a resource name conforms to the restrictions outlined in AIP-122. - if err := resourcename.Validate(in.Name); err != nil { + // check input correctness + if err := s.validateDeleteNullVolumeRequest(in); err != nil { log.Printf("error: %v", err) return nil, err } @@ -129,13 +118,8 @@ func (s *Server) DeleteNullVolume(_ context.Context, in *pb.DeleteNullVolumeRequ // UpdateNullVolume updates a Null volume instance func (s *Server) UpdateNullVolume(_ context.Context, in *pb.UpdateNullVolumeRequest) (*pb.NullVolume, error) { log.Printf("UpdateNullVolume: Received from client: %v", in) - // check required fields - if err := fieldbehavior.ValidateRequiredFields(in); err != nil { - log.Printf("error: %v", err) - return nil, err - } - // Validate that a resource name conforms to the restrictions outlined in AIP-122. - if err := resourcename.Validate(in.NullVolume.Name); err != nil { + // check input correctness + if err := s.validateUpdateNullVolumeRequest(in); err != nil { log.Printf("error: %v", err) return nil, err } @@ -253,13 +237,8 @@ func (s *Server) ListNullVolumes(_ context.Context, in *pb.ListNullVolumesReques // GetNullVolume gets a a Null volume instance func (s *Server) GetNullVolume(_ context.Context, in *pb.GetNullVolumeRequest) (*pb.NullVolume, error) { log.Printf("GetNullVolume: Received from client: %v", in) - // check required fields - if err := fieldbehavior.ValidateRequiredFields(in); err != nil { - log.Printf("error: %v", err) - return nil, err - } - // Validate that a resource name conforms to the restrictions outlined in AIP-122. - if err := resourcename.Validate(in.Name); err != nil { + // check input correctness + if err := s.validateGetNullVolumeRequest(in); err != nil { log.Printf("error: %v", err) return nil, err } @@ -292,13 +271,8 @@ func (s *Server) GetNullVolume(_ context.Context, in *pb.GetNullVolumeRequest) ( // StatsNullVolume gets a Null volume instance stats func (s *Server) StatsNullVolume(_ context.Context, in *pb.StatsNullVolumeRequest) (*pb.StatsNullVolumeResponse, error) { log.Printf("StatsNullVolume: Received from client: %v", in) - // check required fields - if err := fieldbehavior.ValidateRequiredFields(in); err != nil { - log.Printf("error: %v", err) - return nil, err - } - // Validate that a resource name conforms to the restrictions outlined in AIP-122. - if err := resourcename.Validate(in.Name); err != nil { + // check input correctness + if err := s.validateStatsNullVolumeRequest(in); err != nil { log.Printf("error: %v", err) return nil, err } diff --git a/pkg/backend/null_validate.go b/pkg/backend/null_validate.go index 9d9737e3..fd60c374 100644 --- a/pkg/backend/null_validate.go +++ b/pkg/backend/null_validate.go @@ -3,3 +3,62 @@ // Package backend implememnts the BackEnd APIs (network facing) of the storage Server package backend + +import ( + "go.einride.tech/aip/fieldbehavior" + "go.einride.tech/aip/resourceid" + "go.einride.tech/aip/resourcename" + + pb "github.com/opiproject/opi-api/storage/v1alpha1/gen/go" +) + +func (s *Server) validateCreateNullVolumeRequest(in *pb.CreateNullVolumeRequest) error { + // check required fields + if err := fieldbehavior.ValidateRequiredFields(in); err != nil { + return err + } + // see https://google.aip.dev/133#user-specified-ids + if in.NullVolumeId != "" { + if err := resourceid.ValidateUserSettable(in.NullVolumeId); err != nil { + return err + } + } + // TODO: validate also: block_size, blocks_count, uuid + return nil +} + +func (s *Server) validateDeleteNullVolumeRequest(in *pb.DeleteNullVolumeRequest) error { + // check required fields + if err := fieldbehavior.ValidateRequiredFields(in); err != nil { + return err + } + // Validate that a resource name conforms to the restrictions outlined in AIP-122. + return resourcename.Validate(in.Name) +} + +func (s *Server) validateUpdateNullVolumeRequest(in *pb.UpdateNullVolumeRequest) error { + // check required fields + if err := fieldbehavior.ValidateRequiredFields(in); err != nil { + return err + } + // Validate that a resource name conforms to the restrictions outlined in AIP-122. + return resourcename.Validate(in.NullVolume.Name) +} + +func (s *Server) validateGetNullVolumeRequest(in *pb.GetNullVolumeRequest) error { + // check required fields + if err := fieldbehavior.ValidateRequiredFields(in); err != nil { + return err + } + // Validate that a resource name conforms to the restrictions outlined in AIP-122. + return resourcename.Validate(in.Name) +} + +func (s *Server) validateStatsNullVolumeRequest(in *pb.StatsNullVolumeRequest) error { + // check required fields + if err := fieldbehavior.ValidateRequiredFields(in); err != nil { + return err + } + // Validate that a resource name conforms to the restrictions outlined in AIP-122. + return resourcename.Validate(in.Name) +} diff --git a/pkg/backend/nvme_path.go b/pkg/backend/nvme_path.go index ed3ca688..95855c01 100644 --- a/pkg/backend/nvme_path.go +++ b/pkg/backend/nvme_path.go @@ -22,7 +22,6 @@ import ( "go.einride.tech/aip/fieldbehavior" "go.einride.tech/aip/fieldmask" "go.einride.tech/aip/resourceid" - "go.einride.tech/aip/resourcename" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/emptypb" @@ -37,18 +36,14 @@ func sortNvmePaths(paths []*pb.NvmePath) { // CreateNvmePath creates a new Nvme path func (s *Server) CreateNvmePath(_ context.Context, in *pb.CreateNvmePathRequest) (*pb.NvmePath, error) { log.Printf("CreateNvmePath: Received from client: %v", in) - if err := fieldbehavior.ValidateRequiredFields(in); err != nil { + // check input correctness + if err := s.validateCreateNvmePathRequest(in); err != nil { log.Printf("error: %v", err) return nil, err } resourceID := resourceid.NewSystemGenerated() if in.NvmePathId != "" { - err := resourceid.ValidateUserSettable(in.NvmePathId) - if err != nil { - log.Printf("error: %v", err) - return nil, err - } log.Printf("client provided the ID of a resource %v, ignoring the name field %v", in.NvmePathId, in.NvmePath.Name) resourceID = in.NvmePathId } @@ -67,29 +62,9 @@ func (s *Server) CreateNvmePath(_ context.Context, in *pb.CreateNvmePathRequest) return nil, err } - switch in.NvmePath.Trtype { - case pb.NvmeTransportType_NVME_TRANSPORT_PCIE: - if in.NvmePath.Fabrics != nil { - err := status.Errorf(codes.InvalidArgument, "fabrics field is not allowed for pcie transport") - log.Printf("error: %v", err) - return nil, err - } - - if controller.Tcp != nil { - err := status.Errorf(codes.FailedPrecondition, "pcie transport on tcp controller is not allowed") - log.Printf("error: %v", err) - return nil, err - } - case pb.NvmeTransportType_NVME_TRANSPORT_TCP: - fallthrough - case pb.NvmeTransportType_NVME_TRANSPORT_RDMA: - if in.NvmePath.Fabrics == nil { - err := status.Errorf(codes.InvalidArgument, "missing required field for fabrics transports: fabrics") - log.Printf("error: %v", err) - return nil, err - } - default: - err := status.Errorf(codes.InvalidArgument, "not supported transport type: %v", in.NvmePath.Trtype) + // TODO: consider moving to _validate.go + if in.NvmePath.Trtype == pb.NvmeTransportType_NVME_TRANSPORT_PCIE && controller.Tcp != nil { + err := status.Errorf(codes.FailedPrecondition, "pcie transport on tcp controller is not allowed") log.Printf("error: %v", err) return nil, err } @@ -143,19 +118,11 @@ func (s *Server) CreateNvmePath(_ context.Context, in *pb.CreateNvmePathRequest) // DeleteNvmePath deletes a Nvme path func (s *Server) DeleteNvmePath(_ context.Context, in *pb.DeleteNvmePathRequest) (*emptypb.Empty, error) { log.Printf("DeleteNvmePath: Received from client: %v", in) - - // check required fields - if err := fieldbehavior.ValidateRequiredFields(in); err != nil { - log.Printf("error: %v", err) - return nil, err - } - - // Validate that a resource name conforms to the restrictions outlined in AIP-122. - if err := resourcename.Validate(in.Name); err != nil { + // check input correctness + if err := s.validateDeleteNvmePathRequest(in); err != nil { log.Printf("error: %v", err) return nil, err } - nvmePath, ok := s.Volumes.NvmePaths[in.Name] if !ok { if in.AllowMissing { @@ -202,13 +169,8 @@ func (s *Server) DeleteNvmePath(_ context.Context, in *pb.DeleteNvmePathRequest) // UpdateNvmePath updates an Nvme path func (s *Server) UpdateNvmePath(_ context.Context, in *pb.UpdateNvmePathRequest) (*pb.NvmePath, error) { log.Printf("UpdateNvmePath: Received from client: %v", in) - // check required fields - if err := fieldbehavior.ValidateRequiredFields(in); err != nil { - log.Printf("error: %v", err) - return nil, err - } - // Validate that a resource name conforms to the restrictions outlined in AIP-122. - if err := resourcename.Validate(in.NvmePath.Name); err != nil { + // check input correctness + if err := s.validateUpdateNvmePathRequest(in); err != nil { log.Printf("error: %v", err) return nil, err } @@ -274,13 +236,8 @@ func (s *Server) ListNvmePaths(_ context.Context, in *pb.ListNvmePathsRequest) ( // GetNvmePath gets Nvme path func (s *Server) GetNvmePath(_ context.Context, in *pb.GetNvmePathRequest) (*pb.NvmePath, error) { log.Printf("GetNvmePath: Received from client: %v", in) - // check required fields - if err := fieldbehavior.ValidateRequiredFields(in); err != nil { - log.Printf("error: %v", err) - return nil, err - } - // Validate that a resource name conforms to the restrictions outlined in AIP-122. - if err := resourcename.Validate(in.Name); err != nil { + // check input correctness + if err := s.validateGetNvmePathRequest(in); err != nil { log.Printf("error: %v", err) return nil, err } @@ -314,13 +271,8 @@ func (s *Server) GetNvmePath(_ context.Context, in *pb.GetNvmePathRequest) (*pb. // StatsNvmePath gets Nvme path stats func (s *Server) StatsNvmePath(_ context.Context, in *pb.StatsNvmePathRequest) (*pb.StatsNvmePathResponse, error) { log.Printf("StatsNvmePath: Received from client: %v", in) - // check required fields - if err := fieldbehavior.ValidateRequiredFields(in); err != nil { - log.Printf("error: %v", err) - return nil, err - } - // Validate that a resource name conforms to the restrictions outlined in AIP-122. - if err := resourcename.Validate(in.Name); err != nil { + // check input correctness + if err := s.validateStatsNvmePathRequest(in); err != nil { log.Printf("error: %v", err) return nil, err } diff --git a/pkg/backend/nvme_path_validate.go b/pkg/backend/nvme_path_validate.go index 9d9737e3..95fff8c3 100644 --- a/pkg/backend/nvme_path_validate.go +++ b/pkg/backend/nvme_path_validate.go @@ -3,3 +3,86 @@ // Package backend implememnts the BackEnd APIs (network facing) of the storage Server package backend + +import ( + "go.einride.tech/aip/fieldbehavior" + "go.einride.tech/aip/resourceid" + "go.einride.tech/aip/resourcename" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + pb "github.com/opiproject/opi-api/storage/v1alpha1/gen/go" +) + +func (s *Server) validateCreateNvmePathRequest(in *pb.CreateNvmePathRequest) error { + // check required fields + if err := fieldbehavior.ValidateRequiredFields(in); err != nil { + return err + } + // see https://google.aip.dev/133#user-specified-ids + if in.NvmePathId != "" { + if err := resourceid.ValidateUserSettable(in.NvmePathId); err != nil { + return err + } + } + // Validate that a resource name conforms to the restrictions outlined in AIP-122. + if err := resourcename.Validate(in.NvmePath.ControllerNameRef); err != nil { + return err + } + // validate Fabrics and Type coordinated + switch in.NvmePath.Trtype { + case pb.NvmeTransportType_NVME_TRANSPORT_PCIE: + if in.NvmePath.Fabrics != nil { + err := status.Errorf(codes.InvalidArgument, "fabrics field is not allowed for pcie transport") + return err + } + case pb.NvmeTransportType_NVME_TRANSPORT_TCP: + fallthrough + case pb.NvmeTransportType_NVME_TRANSPORT_RDMA: + if in.NvmePath.Fabrics == nil { + err := status.Errorf(codes.InvalidArgument, "missing required field for fabrics transports: fabrics") + return err + } + default: + err := status.Errorf(codes.InvalidArgument, "not supported transport type: %v", in.NvmePath.Trtype) + return err + } + return nil +} + +func (s *Server) validateDeleteNvmePathRequest(in *pb.DeleteNvmePathRequest) error { + // check required fields + if err := fieldbehavior.ValidateRequiredFields(in); err != nil { + return err + } + // Validate that a resource name conforms to the restrictions outlined in AIP-122. + return resourcename.Validate(in.Name) +} + +func (s *Server) validateUpdateNvmePathRequest(in *pb.UpdateNvmePathRequest) error { + // check required fields + if err := fieldbehavior.ValidateRequiredFields(in); err != nil { + return err + } + // Validate that a resource name conforms to the restrictions outlined in AIP-122. + return resourcename.Validate(in.NvmePath.Name) +} + +func (s *Server) validateGetNvmePathRequest(in *pb.GetNvmePathRequest) error { + // check required fields + if err := fieldbehavior.ValidateRequiredFields(in); err != nil { + return err + } + // Validate that a resource name conforms to the restrictions outlined in AIP-122. + return resourcename.Validate(in.Name) +} + +func (s *Server) validateStatsNvmePathRequest(in *pb.StatsNvmePathRequest) error { + // check required fields + if err := fieldbehavior.ValidateRequiredFields(in); err != nil { + return err + } + // Validate that a resource name conforms to the restrictions outlined in AIP-122. + return resourcename.Validate(in.Name) +}