mirror of
https://github.com/cristicalin/synology-csi.git
synced 2026-05-07 13:32:38 +00:00
581 lines
13 KiB
Go
581 lines
13 KiB
Go
/*
|
|
* Copyright 2022 Synology Inc.
|
|
*/
|
|
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
"github.com/spf13/cobra"
|
|
"github.com/SynologyOpenSource/synology-csi/pkg/dsm/webapi"
|
|
"github.com/SynologyOpenSource/synology-csi/pkg/utils"
|
|
"strconv"
|
|
|
|
"text/tabwriter"
|
|
)
|
|
|
|
var cmdShare = &cobra.Command{
|
|
Use: "share",
|
|
Short: "share API",
|
|
Long: `DSM share API`,
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
cmd.Help()
|
|
},
|
|
}
|
|
|
|
var cmdShareGet = &cobra.Command{
|
|
Use: "get <name>",
|
|
Short: "get share",
|
|
Args: cobra.MinimumNArgs(1),
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
dsm, err := LoginDsmForTest()
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
defer func() {
|
|
dsm.Logout()
|
|
}()
|
|
|
|
share, err := dsm.ShareGet(args[0])
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
fmt.Printf("Success, ShareGet(%s) = %#v\n", args[0], share)
|
|
},
|
|
}
|
|
|
|
var cmdShareList = &cobra.Command{
|
|
Use: "list",
|
|
Short: "list shares",
|
|
Args: cobra.MinimumNArgs(0),
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
dsm, err := LoginDsmForTest()
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
defer func() {
|
|
dsm.Logout()
|
|
}()
|
|
|
|
shares, err := dsm.ShareList()
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
tw := tabwriter.NewWriter(os.Stdout, 8, 0, 2, ' ', 0)
|
|
|
|
fmt.Fprintf(tw, "%s\t%-32s\t%-10s\t%-64s\t%s\t%s\t%s\t%s\t%-10s\t%s\t%s\n",
|
|
"id:", "Name:", "VolPath", "Desc:", "Quota(MB):", "ShareCow:", "RecycleBin:", "RBAdminOnly:", "Encryption:", "CanSnap:", "Uuid:")
|
|
for i, info := range shares {
|
|
fmt.Fprintf(tw, "%d\t%-32s\t", i, info.Name)
|
|
fmt.Fprintf(tw, "%-10s\t", info.VolPath)
|
|
fmt.Fprintf(tw, "%-64s\t", info.Desc)
|
|
fmt.Fprintf(tw, "%d\t", info.QuotaValueInMB)
|
|
fmt.Fprintf(tw, "%v\t", info.EnableShareCow)
|
|
fmt.Fprintf(tw, "%v\t", info.EnableRecycleBin)
|
|
fmt.Fprintf(tw, "%v\t", info.RecycleBinAdminOnly)
|
|
fmt.Fprintf(tw, "%-10d\t", info.Encryption)
|
|
fmt.Fprintf(tw, "%v\t", info.SupportSnapshot)
|
|
fmt.Fprintf(tw, "%s\t", info.Uuid)
|
|
fmt.Fprintf(tw, "\n")
|
|
|
|
_ = tw.Flush()
|
|
}
|
|
|
|
fmt.Printf("Success, ShareList()\n")
|
|
},
|
|
}
|
|
|
|
var cmdShareCreate = &cobra.Command{
|
|
Use: "create <name> <location> [<size_bytes>]",
|
|
Short: "create share",
|
|
Args: cobra.MinimumNArgs(2),
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
dsm, err := LoginDsmForTest()
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
defer func() {
|
|
dsm.Logout()
|
|
}()
|
|
|
|
var size int64 = 0
|
|
if len(args) >= 3 {
|
|
size, err = strconv.ParseInt(args[2], 10, 64)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
sizeInMB := utils.BytesToMBCeil(size)
|
|
testSpec := webapi.ShareCreateSpec{
|
|
Name: args[0],
|
|
ShareInfo: webapi.ShareInfo{
|
|
Name: args[0],
|
|
VolPath: args[1],
|
|
Desc: "Created by synocli",
|
|
EnableShareCow: false,
|
|
EnableRecycleBin: true,
|
|
RecycleBinAdminOnly: true,
|
|
Encryption: 0,
|
|
QuotaForCreate: &sizeInMB,
|
|
},
|
|
}
|
|
|
|
fmt.Printf("spec = %#v, sizeInMB = %d\n", testSpec, sizeInMB)
|
|
err = dsm.ShareCreate(testSpec)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
share, err := dsm.ShareGet(args[0])
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
fmt.Printf("Success, ShareCreate(%s) resp = %#v\n", args[0], share)
|
|
},
|
|
}
|
|
|
|
var cmdShareDelete = &cobra.Command{
|
|
Use: "delete <name>",
|
|
Short: "delete share",
|
|
Args: cobra.MinimumNArgs(1),
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
dsm, err := LoginDsmForTest()
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
defer func() {
|
|
dsm.Logout()
|
|
}()
|
|
|
|
err = dsm.ShareDelete(args[0])
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
fmt.Printf("Success, ShareDelete(%s)\n", args[0])
|
|
},
|
|
}
|
|
|
|
var cmdShareClone = &cobra.Command{
|
|
Use: "clone <new name> <src name> <is_snapshot [true|false]>",
|
|
Short: "clone share",
|
|
Args: cobra.MinimumNArgs(2),
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
dsm, err := LoginDsmForTest()
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
defer func() {
|
|
dsm.Logout()
|
|
}()
|
|
|
|
fromSnapshot := false
|
|
if len(args) >= 3 && args[2] == "true" {
|
|
fromSnapshot = true
|
|
}
|
|
|
|
newName := args[0]
|
|
srcName := args[1]
|
|
orgShareName := ""
|
|
snapshot := ""
|
|
if fromSnapshot {
|
|
snapshot = srcName
|
|
shares, err := dsm.ShareList()
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
for _, share := range shares {
|
|
snaps, err := dsm.ShareSnapshotList(share.Name)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
for _, snap := range snaps {
|
|
if snap.Time != srcName {
|
|
continue
|
|
}
|
|
orgShareName = share.Name
|
|
break
|
|
}
|
|
if orgShareName != "" {
|
|
break
|
|
}
|
|
}
|
|
|
|
if orgShareName == "" {
|
|
fmt.Println("Failed to find org Share of the snapshot")
|
|
os.Exit(1)
|
|
}
|
|
} else {
|
|
orgShareName = srcName
|
|
}
|
|
srcShare, err := dsm.ShareGet(orgShareName)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
shareSpec := webapi.ShareCloneSpec{
|
|
Name: newName,
|
|
Snapshot: snapshot,
|
|
ShareInfo: webapi.ShareInfo{
|
|
Name: newName,
|
|
VolPath: srcShare.VolPath,
|
|
Desc: "Cloned from "+srcName+" by synocli",
|
|
EnableRecycleBin: srcShare.EnableRecycleBin,
|
|
RecycleBinAdminOnly: srcShare.RecycleBinAdminOnly,
|
|
NameOrg: orgShareName,
|
|
},
|
|
}
|
|
fmt.Printf("newName: %s, fromSnapshot: %v (%s), orgShareName: %s\n", newName, fromSnapshot, snapshot, orgShareName)
|
|
_, err = dsm.ShareClone(shareSpec)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
share, err := dsm.ShareGet(newName)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
fmt.Printf("Success, ShareClone(%s, %s) new share = %#v\n", newName, srcName, share)
|
|
},
|
|
}
|
|
|
|
var cmdShareSnapshotCreate = &cobra.Command{
|
|
Use: "snap_create <src name> <desc> <is_lock [true|false]>",
|
|
Short: "create share snapshot (only share located in btrfs volume can take snapshots)",
|
|
Args: cobra.MinimumNArgs(3),
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
dsm, err := LoginDsmForTest()
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
defer func() {
|
|
dsm.Logout()
|
|
}()
|
|
|
|
spec := webapi.ShareSnapshotCreateSpec{
|
|
ShareName: args[0],
|
|
Desc: args[1],
|
|
IsLocked: utils.StringToBoolean(args[2]),
|
|
}
|
|
|
|
fmt.Printf("spec = %#v\n", spec)
|
|
snapTime, err := dsm.ShareSnapshotCreate(spec)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
fmt.Printf("resp = %s\n", snapTime)
|
|
|
|
snaps, err := dsm.ShareSnapshotList(spec.ShareName)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
var snapshot webapi.ShareSnapshotInfo
|
|
for _, snap := range snaps {
|
|
if snap.Time == snapTime {
|
|
snapshot = snap
|
|
break
|
|
}
|
|
}
|
|
|
|
fmt.Printf("Success, ShareSnapshotCreate(%s), snap = %#v\n", args[0], snapshot)
|
|
},
|
|
}
|
|
|
|
var cmdShareSnapshotDelete = &cobra.Command{
|
|
Use: "snap_delete <share name> <snapshot time>",
|
|
Short: "delete share snapshot",
|
|
Args: cobra.MinimumNArgs(2),
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
dsm, err := LoginDsmForTest()
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
defer func() {
|
|
dsm.Logout()
|
|
}()
|
|
|
|
if err := dsm.ShareSnapshotDelete(args[1], args[0]); err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
fmt.Printf("Success, ShareSnapshotDelete(%s, %s)\n", args[1], args[0])
|
|
},
|
|
}
|
|
|
|
func shareSnapshotListAll(dsm *webapi.DSM, shareName string) ([]webapi.ShareSnapshotInfo, error) {
|
|
if shareName != "" {
|
|
return dsm.ShareSnapshotList(shareName)
|
|
}
|
|
|
|
var infos []webapi.ShareSnapshotInfo
|
|
shares, err := dsm.ShareList()
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return nil, err
|
|
}
|
|
|
|
for _, share := range shares {
|
|
snaps, err := dsm.ShareSnapshotList(share.Name)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return nil, err
|
|
}
|
|
infos = append(infos, snaps...)
|
|
}
|
|
|
|
return infos, nil
|
|
}
|
|
|
|
var cmdShareSnapshotList = &cobra.Command{
|
|
Use: "snap_list [<share name>]",
|
|
Short: "list share snapshots",
|
|
Args: cobra.MinimumNArgs(0),
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
dsm, err := LoginDsmForTest()
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
defer func() {
|
|
dsm.Logout()
|
|
}()
|
|
|
|
shareName := ""
|
|
if len(args) >= 1 {
|
|
shareName = args[0]
|
|
}
|
|
|
|
snaps, err := shareSnapshotListAll(dsm, shareName)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
tw := tabwriter.NewWriter(os.Stdout, 8, 0, 2, ' ', 0)
|
|
|
|
fmt.Fprintf(tw, "id:\tTime:\tDesc:\tLock:\tScheduleSnapshot:\n")
|
|
for i, info := range snaps {
|
|
fmt.Fprintf(tw, "%d\t%-32s\t", i, info.Time)
|
|
fmt.Fprintf(tw, "%-32s\t", info.Desc)
|
|
fmt.Fprintf(tw, "%v\t", info.Lock)
|
|
fmt.Fprintf(tw, "%v\t", info.ScheduleSnapshot)
|
|
fmt.Fprintf(tw, "\n")
|
|
|
|
_ = tw.Flush()
|
|
}
|
|
fmt.Printf("Success, ShareSnapList(%s)\n", shareName)
|
|
},
|
|
}
|
|
|
|
func createSharePermission(name string, acl string) *webapi.SharePermission {
|
|
var permission webapi.SharePermission
|
|
permission.Name = name
|
|
|
|
switch strings.ToLower(acl) {
|
|
case "rw":
|
|
permission.IsWritable = true
|
|
case "ro":
|
|
permission.IsReadonly = true
|
|
case "no":
|
|
permission.IsDeny = true
|
|
default:
|
|
fmt.Println("[ERROR] Unknown ACL")
|
|
return nil
|
|
}
|
|
return &permission
|
|
}
|
|
|
|
func getShareLocalUserPermission(dsm *webapi.DSM, shareName string, userName string) (*webapi.SharePermission, error) {
|
|
infos, err := dsm.SharePermissionList(shareName, "local_user")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, info := range infos {
|
|
if info.Name == userName {
|
|
return &info, nil
|
|
}
|
|
}
|
|
return nil, fmt.Errorf("Permission Not Found.")
|
|
}
|
|
|
|
var cmdSharePermissionList = &cobra.Command{
|
|
Use: "permission_list <name> [local_user|local_group|system]",
|
|
Short: "list permissions",
|
|
Args: cobra.MinimumNArgs(1),
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
dsm, err := LoginDsmForTest()
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
defer func() {
|
|
dsm.Logout()
|
|
}()
|
|
|
|
userGroupType := "local_user"
|
|
if len(args) >= 2 {
|
|
userGroupType = args[1]
|
|
}
|
|
|
|
infos, err := dsm.SharePermissionList(args[0], userGroupType)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
tw := tabwriter.NewWriter(os.Stdout, 8, 0, 2, ' ', 0)
|
|
|
|
fmt.Fprintf(tw, "%s\t%-20s\t%-10s\t%-12s\t%-12s\t%-10s\t%-10s\n", "id:", "Name:", "IsAdmin", "IsReadonly:", "IsWritable:", "IsDeny:", "IsCustom:")
|
|
for i, info := range infos {
|
|
fmt.Fprintf(tw, "%d\t", i)
|
|
fmt.Fprintf(tw, "%-20s\t", info.Name)
|
|
fmt.Fprintf(tw, "%-10v\t", info.IsAdmin)
|
|
fmt.Fprintf(tw, "%-12v\t", info.IsReadonly)
|
|
fmt.Fprintf(tw, "%-12v\t", info.IsWritable)
|
|
fmt.Fprintf(tw, "%-10v\t", info.IsDeny)
|
|
fmt.Fprintf(tw, "%-10v\t", info.IsCustom)
|
|
fmt.Fprintf(tw, "\n")
|
|
|
|
_ = tw.Flush()
|
|
}
|
|
|
|
fmt.Printf("Success, SharePermissionList(%s)\n", args[0])
|
|
},
|
|
}
|
|
|
|
var cmdSharePermissionSet = &cobra.Command{
|
|
Use: "permission_set <share name> <username> <[rw|ro|no]>",
|
|
Short: "set permission",
|
|
Args: cobra.MinimumNArgs(3),
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
dsm, err := LoginDsmForTest()
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
defer func() {
|
|
dsm.Logout()
|
|
}()
|
|
|
|
shareName := args[0]
|
|
userName := args[1]
|
|
userGroupType := "local_user"
|
|
permission := createSharePermission(userName, args[2])
|
|
if permission == nil {
|
|
fmt.Println("Failed. Invalid Argument.")
|
|
os.Exit(1)
|
|
}
|
|
permissions := append([]*webapi.SharePermission{}, permission)
|
|
|
|
spec := webapi.SharePermissionSetSpec{
|
|
Name: shareName,
|
|
UserGroupType: userGroupType,
|
|
Permissions: permissions,
|
|
}
|
|
|
|
fmt.Printf("spec = %#v\n", spec)
|
|
if err := dsm.SharePermissionSet(spec); err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
newPermission, err := getShareLocalUserPermission(dsm, shareName, userName)
|
|
if err != nil {
|
|
fmt.Printf("Failed to get share local_user permission(%s, %s): %v\n", shareName, userName, err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
fmt.Printf("Success, SharePermissionSet(%s), newPermission: %#v\n", shareName, newPermission)
|
|
},
|
|
}
|
|
|
|
var cmdShareSet = &cobra.Command{
|
|
Use: "set <share name> <new size>",
|
|
Short: "share set (only share located in btrfs volume can be resized)",
|
|
Args: cobra.MinimumNArgs(2),
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
dsm, err := LoginDsmForTest()
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
defer func() {
|
|
dsm.Logout()
|
|
}()
|
|
|
|
shareName := args[0]
|
|
newSize, err := strconv.ParseInt(args[1], 10, 64)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
share, err := dsm.ShareGet(shareName)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
fmt.Printf("old = %#v\n", share)
|
|
|
|
newSizeInMB := utils.BytesToMBCeil(newSize)
|
|
updateInfo := webapi.ShareUpdateInfo{
|
|
Name: share.Name,
|
|
VolPath: share.VolPath,
|
|
QuotaForCreate: &newSizeInMB,
|
|
}
|
|
if err := dsm.ShareSet(shareName, updateInfo); err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
newShare, err := dsm.ShareGet(shareName)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
os.Exit(1)
|
|
}
|
|
fmt.Printf("new = %#v\n", newShare)
|
|
|
|
fmt.Printf("Success, ShareSet(%s), quota: %v -> %v MB\n", shareName, share.QuotaValueInMB, newShare.QuotaValueInMB)
|
|
},
|
|
}
|
|
|
|
|
|
func init() {
|
|
cmdShare.AddCommand(cmdShareGet)
|
|
cmdShare.AddCommand(cmdShareCreate)
|
|
cmdShare.AddCommand(cmdShareDelete)
|
|
cmdShare.AddCommand(cmdShareList)
|
|
cmdShare.AddCommand(cmdShareClone)
|
|
cmdShare.AddCommand(cmdShareSnapshotCreate)
|
|
cmdShare.AddCommand(cmdShareSnapshotDelete)
|
|
cmdShare.AddCommand(cmdShareSnapshotList)
|
|
|
|
cmdShare.AddCommand(cmdSharePermissionList)
|
|
cmdShare.AddCommand(cmdSharePermissionSet)
|
|
cmdShare.AddCommand(cmdShareSet)
|
|
}
|