mirror of
https://github.com/oracle/zfssa-csi-driver.git
synced 2025-06-28 14:36:59 +00:00
204 lines
5.9 KiB
Go
204 lines
5.9 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 (
|
|
"github.com/oracle/zfssa-csi-driver/pkg/utils"
|
|
"context"
|
|
"fmt"
|
|
"strconv"
|
|
"google.golang.org/grpc/codes"
|
|
grpcStatus "google.golang.org/grpc/status"
|
|
"net/http"
|
|
)
|
|
|
|
type Filesystem struct {
|
|
MountPoint string `json:"mountpoint"`
|
|
CreationTime string `json:"creation"`
|
|
RootUser string `json:"root_user"`
|
|
RootGroup string `json:"root_group"`
|
|
RootPermissions string `json:"root_permissions"`
|
|
RestrictChown bool `json:"rstchown"`
|
|
ShareNFS string `json:"sharenfs"`
|
|
ShareSMB string `json:"sharesmb"`
|
|
SpaceData int64 `json:"space_data"`
|
|
CanonicalName string `json:"canonical_name"`
|
|
RecordSize int64 `json:"recordsize"`
|
|
SpaceAvailable int64 `json:"space_available"`
|
|
Quota int64 `json:"quota"`
|
|
UTF8Only bool `json:"utf8only"`
|
|
MaxBlockSize int64 `json:"maxblocksize"`
|
|
Atime bool `json:"atime"`
|
|
ReadOnly bool `json:"readonly"`
|
|
Pool string `json:"pool"`
|
|
Name string `json:"name"`
|
|
SpaceTotal int64 `json:"space_total"`
|
|
SpaceUnused int64 `json:"space_unused_res"`
|
|
Project string `json:"project"`
|
|
Href string `json:"href"`
|
|
}
|
|
|
|
type filesystemJSON struct {
|
|
FileSystem Filesystem `json:"filesystem"`
|
|
}
|
|
|
|
type filesystems struct {
|
|
List []Filesystem `json:"filesystems"`
|
|
}
|
|
|
|
// This variable provides a mapping between the name of the parameters used in the storage
|
|
// class yaml file and the name of equivalent parameters of the appliance.
|
|
var yml2fsProperty = map[string]string {
|
|
"rootUser":"root_user",
|
|
"rootGroup":"root_group",
|
|
"rootPermissions":"root_permissions",
|
|
"shareNFS":"sharenfs",
|
|
"restrictChown":"rstchown",
|
|
}
|
|
|
|
func CreateFilesystem(ctx context.Context, token *Token, fsname string, volSize int64,
|
|
parameters *map[string]string) (*Filesystem, int, error) {
|
|
|
|
pool := (*parameters)["pool"]
|
|
project := (*parameters)["project"]
|
|
url := fmt.Sprintf(zFilesystems, token.Name, pool, project)
|
|
reqBody := buildFilesystemReq(ctx, fsname, volSize, parameters)
|
|
rspBody := new(filesystemJSON)
|
|
|
|
_, code, err := MakeRequest(ctx, token, "POST", url, reqBody, http.StatusCreated, rspBody)
|
|
if err != nil {
|
|
return nil, code, err
|
|
}
|
|
|
|
utils.GetLogCTRL(ctx, 5).Println("CreateFilesystem succeeded") // ***
|
|
|
|
return &rspBody.FileSystem, code, nil
|
|
}
|
|
|
|
// Builds the body of the "create file system" request
|
|
func buildFilesystemReq(ctx context.Context, name string, volSize int64,
|
|
parameters *map[string]string) *map[string]interface{} {
|
|
|
|
fsReq := make(map[string]interface{})
|
|
|
|
fsReq["name"] = name
|
|
fsReq["quota"] = volSize
|
|
fsReq["reservation"] = volSize
|
|
|
|
for key, param := range *parameters {
|
|
fsProp, ok := yml2fsProperty[key]
|
|
if ok {
|
|
switch fsProp {
|
|
case "rstchown":
|
|
val, err := strconv.ParseBool(param)
|
|
if err != nil {
|
|
utils.GetLogREST(ctx, 2).Println("Invalid restrict chown, will use default: true",
|
|
"rstchown", param)
|
|
val = true
|
|
}
|
|
fsReq[fsProp] = val
|
|
default:
|
|
fsReq[fsProp] = param
|
|
}
|
|
utils.GetLogREST(ctx, 5).Println("BuildFSRequest", "key", key, "value", param)
|
|
}
|
|
}
|
|
|
|
return &fsReq
|
|
}
|
|
|
|
func GetFilesystem(ctx context.Context, token *Token, pool, project, filesystem string) (
|
|
*Filesystem, int, error) {
|
|
|
|
url := fmt.Sprintf(zFilesystem, token.Name, pool, project, filesystem)
|
|
|
|
rspJSON := &filesystemJSON{}
|
|
_, httpStatus, err := MakeRequest(ctx, token, "GET", url, nil, http.StatusOK, rspJSON)
|
|
if err != nil {
|
|
return nil, httpStatus, err
|
|
}
|
|
|
|
return &rspJSON.FileSystem, httpStatus, nil
|
|
}
|
|
|
|
func ModifyFilesystem(ctx context.Context, token *Token, href string,
|
|
parameters *map[string]interface{}) (*Filesystem, int, error) {
|
|
|
|
url := fmt.Sprintf(zAppliance + href, token.Name)
|
|
|
|
rspJSON := &filesystemJSON{}
|
|
_, httpStatus, err := MakeRequest(ctx, token, "PUT", url, parameters, http.StatusAccepted, rspJSON)
|
|
if err != nil {
|
|
return nil, httpStatus, err
|
|
}
|
|
|
|
return &rspJSON.FileSystem, httpStatus, nil
|
|
}
|
|
|
|
func DeleteFilesystem(ctx context.Context, token *Token, hRef string) (bool, int, error) {
|
|
|
|
utils.GetLogREST(ctx, 5).Println("DeleteFilesystem", "appliance", token.Name, "Filesystem", hRef)
|
|
|
|
url := fmt.Sprintf(zAppliance + hRef, token.Name)
|
|
|
|
_, 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("DeleteFilesystem", "http status", httpStatus)
|
|
if httpStatus >= 200 && httpStatus < 300 {
|
|
return false, httpStatus, nil
|
|
}
|
|
}
|
|
|
|
return true, httpStatus, nil
|
|
}
|
|
|
|
// Returns the List of filesystems associated with the pool and project passed in. To
|
|
// get a system wide List of file systems, the pool AND the project must be 'nil'
|
|
func GetFilesystems(ctx context.Context, token *Token, pool, project string) ([]Filesystem, error) {
|
|
|
|
var url string
|
|
if pool != "" && project != "" {
|
|
url = fmt.Sprintf(zFilesystems, token.Name, pool, project)
|
|
} else if pool == "" && project == "" {
|
|
url = fmt.Sprintf(zAllFilesystems, token.Name)
|
|
} else {
|
|
return nil, grpcStatus.Error(codes.InvalidArgument, "pool and project must be both nil or both not nil")
|
|
}
|
|
|
|
filesystems := new(filesystems)
|
|
filesystems.List = make([]Filesystem, 0)
|
|
|
|
_, _, err := MakeRequest(ctx, token, "GET", url, nil, http.StatusOK, filesystems)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return filesystems.List, nil
|
|
}
|
|
|
|
func (l *filesystems) UnmarshalJSON(b []byte) error {
|
|
return zfssaUnmarshalList(b, &l.List)
|
|
}
|
|
|
|
func CloneFileSystemSnapshot(ctx context.Context, token *Token, hRef string,
|
|
parameters map[string]interface{}) (*Filesystem, int, error) {
|
|
|
|
url := fmt.Sprintf(zAppliance + hRef + "/clone", token.Name)
|
|
|
|
rspBody := new(filesystemJSON)
|
|
|
|
_, code, err := MakeRequest(ctx, token, "PUT", url, ¶meters, http.StatusCreated, rspBody)
|
|
if err != nil {
|
|
return nil, code, err
|
|
}
|
|
|
|
return &rspBody.FileSystem, code, nil
|
|
}
|