mirror of
https://github.com/oracle/zfssa-csi-driver.git
synced 2025-06-28 14:36:59 +00:00
202 lines
5.5 KiB
Go
202 lines
5.5 KiB
Go
/*
|
|
* Copyright (c) 2021, Oracle and/or its affiliates.
|
|
* Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
|
|
*/
|
|
|
|
package zfssarest
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/oracle/zfssa-csi-driver/pkg/utils"
|
|
"google.golang.org/grpc/codes"
|
|
grpcStatus "google.golang.org/grpc/status"
|
|
)
|
|
|
|
const (
|
|
DefaultBlockSize int = 8192
|
|
DevicePathKey string = "devicePath"
|
|
MaskAll string = "com.sun.ms.vss.hg.maskAll"
|
|
)
|
|
|
|
type Lun struct {
|
|
SpaceData float64 `json:"space_data"`
|
|
CanonicalName string `json:"canonical_name"`
|
|
VolumeSize float64 `json:"volsize"`
|
|
VolumeBlockSize int64 `json:"volblocksize"`
|
|
Pool string `json:"pool"`
|
|
Project string `json:"project"`
|
|
Name string `json:"name"`
|
|
Href string `json:"href"`
|
|
AssignedNumber []int32 `json:"assignednumber"`
|
|
InitiatorGroup []string `json:"initiatorgroup"`
|
|
TargetGroup string `json:"targetgroup"`
|
|
}
|
|
|
|
type LunJson struct {
|
|
LUN Lun `json:"lun"`
|
|
}
|
|
|
|
type Luns struct {
|
|
List []Lun `json:"luns"`
|
|
}
|
|
|
|
type LunInitiatorGrps struct {
|
|
InitiatorGroup []string `json:"initiatorgroup"`
|
|
}
|
|
|
|
type createLunRequest struct {
|
|
Name string `json:"name"`
|
|
Size int64 `json:"volsize"`
|
|
Blocksize int `json:"volblocksize"`
|
|
TargetGroup string `json:"targetgroup"`
|
|
Sparse bool `json:"sparse"`
|
|
InitiatorGroup []string `json:"initiatorgroup"`
|
|
}
|
|
|
|
func CreateLUN(ctx context.Context, token *Token, lunName string, volSize int64,
|
|
parameters *map[string]string) (*utils.VolumeId, *Lun, int, error) {
|
|
|
|
pool := (*parameters)["pool"]
|
|
project := (*parameters)["project"]
|
|
|
|
url := fmt.Sprintf(zLUNs, token.Name, pool, project)
|
|
|
|
blockSizeString := (*parameters)["blockSize"]
|
|
blockSize, err := strconv.Atoi(blockSizeString)
|
|
if err != nil {
|
|
utils.GetLogREST(ctx, 2).Println("Invalid block size, will use default",
|
|
"requested_block_size", blockSizeString, "default_block_size", DefaultBlockSize)
|
|
blockSize = DefaultBlockSize
|
|
}
|
|
|
|
volTypeString := (*parameters)["volumeType"]
|
|
sparse := false
|
|
if volTypeString == "thin" {
|
|
sparse = true
|
|
}
|
|
|
|
reqBody := createLunRequest{
|
|
Name: lunName,
|
|
Size: volSize,
|
|
Blocksize: blockSize,
|
|
TargetGroup: (*parameters)["targetGroup"],
|
|
Sparse: sparse,
|
|
InitiatorGroup: []string{MaskAll},
|
|
}
|
|
|
|
rspBody := &LunJson{}
|
|
_, code, err := MakeRequest(ctx, token, "POST", url, reqBody, http.StatusCreated, rspBody)
|
|
if err != nil {
|
|
return nil, nil, code, err
|
|
}
|
|
|
|
volumeId := utils.NewVolumeId(utils.BlockVolume, token.Name, pool, project, lunName)
|
|
|
|
return volumeId, &rspBody.LUN, code, nil
|
|
}
|
|
|
|
func GetLun(ctx context.Context, token *Token, pool, project, lun string) (*Lun, int, error) {
|
|
|
|
url := fmt.Sprintf(zLUN, token.Name, pool, project, lun)
|
|
|
|
rspJSON := &LunJson{}
|
|
_, httpStatus, err := MakeRequest(ctx, token, "GET", url, nil, http.StatusOK, rspJSON)
|
|
if err != nil {
|
|
return nil, httpStatus, err
|
|
}
|
|
|
|
return &rspJSON.LUN, httpStatus, nil
|
|
}
|
|
|
|
// Returns the List of LUNs belonging to the pool and project passed in. To
|
|
// get a system wide List of LUNs, the pool AND the project must be 'nil'
|
|
func GetLuns(ctx context.Context, token *Token, pool, project string) ([]Lun, error) {
|
|
|
|
var url string
|
|
if pool != "" && project != "" {
|
|
url = fmt.Sprintf(zLUNs, token.Name, pool, project)
|
|
} else if pool == "" && project == "" {
|
|
url = fmt.Sprintf(zAllLUNs, token.Name)
|
|
} else {
|
|
return nil, grpcStatus.Error(codes.InvalidArgument, "pool and project must be both nil or both not nil")
|
|
}
|
|
|
|
luns := new(Luns)
|
|
luns.List = make([]Lun, 0)
|
|
|
|
_, _, err := MakeRequest(ctx, token, "GET", url, nil, http.StatusOK, luns)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return luns.List, nil
|
|
}
|
|
|
|
func DeleteLun(ctx context.Context, token *Token, pool, project, lun string) (bool, int, error) {
|
|
|
|
url := fmt.Sprintf(zLUN, token.Name, pool, project, lun)
|
|
|
|
_, httpStatus, err := MakeRequest(ctx, token, "DELETE", url, nil, http.StatusNoContent, nil)
|
|
if err != nil {
|
|
return false, httpStatus, err
|
|
}
|
|
|
|
if httpStatus != http.StatusNoContent {
|
|
utils.GetLogREST(ctx, 5).Println("DeleteLun", "http status", httpStatus)
|
|
if httpStatus >= 200 && httpStatus < 300 {
|
|
return false, httpStatus, nil
|
|
}
|
|
}
|
|
|
|
return true, httpStatus, nil
|
|
}
|
|
|
|
func GetInitiatorGroupList(ctx context.Context, token *Token, pool, project,
|
|
lun string) ([]string, error) {
|
|
|
|
url := fmt.Sprintf(zLUN, token.Name, pool, project, lun)
|
|
|
|
rspBody := &LunJson{}
|
|
_, _, err := MakeRequest(ctx, token, "GET", url, nil, http.StatusOK, rspBody)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
utils.GetLogREST(ctx, 2).Printf("Retrieved the initiator list: {}", rspBody)
|
|
|
|
return rspBody.LUN.InitiatorGroup, nil
|
|
}
|
|
|
|
func SetInitiatorGroupList(ctx context.Context, token *Token, pool, project, lun,
|
|
group string) (int, error) {
|
|
|
|
url := fmt.Sprintf(zLUN, token.Name, pool, project, lun)
|
|
|
|
reqBody := &LunInitiatorGrps{InitiatorGroup: []string{group}}
|
|
utils.GetLogREST(ctx, 2).Printf("Setting up initiator list: {}", reqBody)
|
|
_, code, err := MakeRequest(ctx, token, "PUT", url, reqBody, http.StatusAccepted, nil)
|
|
return code, err
|
|
}
|
|
|
|
func (l *Luns) UnmarshalJSON(b []byte) error {
|
|
return zfssaUnmarshalList(b, &l.List)
|
|
}
|
|
|
|
func CloneLunSnapshot(ctx context.Context, token *Token, hRef string,
|
|
parameters map[string]interface{}) (*Lun, int, error) {
|
|
|
|
url := fmt.Sprintf(zAppliance + hRef + "/clone", token.Name)
|
|
|
|
rspBody := new(LunJson)
|
|
|
|
_, code, err := MakeRequest(ctx, token, "PUT", url, ¶meters, http.StatusCreated, rspBody)
|
|
if err != nil {
|
|
return nil, code, err
|
|
}
|
|
|
|
return &rspBody.LUN, code, nil
|
|
}
|