|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563 |
- package userspace
-
- import (
- "fmt"
- "strconv"
- "strings"
-
- "github.com/chzyer/readline"
- "github.com/spf13/cobra"
- "gitlink.org.cn/cloudream/jcs-pub/client/sdk/api/v1"
-
- cortypes "gitlink.org.cn/cloudream/jcs-pub/coordinator/types"
- "gitlink.org.cn/cloudream/jcs-pub/jcsctl/cmd"
- )
-
- type MyUserSpace struct {
- api.UserSpaceCreate
- }
-
- func init() {
- cmd := cobra.Command{
- Use: "create",
- Short: "add a new cloud storage",
- Run: func(c *cobra.Command, args []string) {
- ctx := cmd.GetCmdCtx(c)
- create(c, ctx)
- },
- }
- UserSpaceCmd.AddCommand(&cmd)
- }
-
- func create(c *cobra.Command, ctx *cmd.CommandContext) {
- var userSpace MyUserSpace
-
- rl, err := readline.New("> ")
- if err != nil {
- fmt.Printf("初始化命令行失败: %v\n", err)
- return
- }
- defer rl.Close()
-
- rl.SetPrompt("\033[36m请输入存储服务名称(Name): \033[0m")
- name, err := rl.Readline()
- if err != nil {
- return
- }
- userSpace.Name = name
-
- storageType, err := promptSelectStorage()
- if err != nil {
- return
- }
-
- switch storageType {
- case "Local":
- err = userSpace.collectLocalConfig(rl)
- case "OBS":
- err = userSpace.collectObsConfig(rl)
- case "OSS":
- err = userSpace.collectOssConfig(rl)
- case "COS":
- err = userSpace.collectCosConfig(rl)
- case "EFile":
- err = userSpace.collectEfileConfig(rl)
- case "S3":
- err = userSpace.collectS3Config(rl)
- }
- if err != nil {
- return
- }
-
- err = userSpace.collectShardStore(rl)
- if err != nil {
- return
- }
-
- err = userSpace.collectWorkingDir(rl)
- if err != nil {
- return
- }
-
- _, err = ctx.Client.UserSpaceCreate(userSpace.UserSpaceCreate)
- if err != nil {
- fmt.Printf("\033[31m保存配置失败: %v\033[0m", err)
- return
- }
- fmt.Println("\033[32m配置保存成功!\033[0m")
- }
-
- func promptSelectStorage() (string, error) {
- rl, _ := readline.NewEx(&readline.Config{
- Prompt: "\033[36m»\033[0m ",
- HistoryFile: "/tmp/storage_history.txt",
- InterruptPrompt: "^C",
- })
- defer rl.Close()
-
- fmt.Println("\033[1;36m请选择存储类型(StorageType):\033[0m")
- options := []string{"Local", "OBS", "OSS", "COS", "EFile", "S3"}
- for i, option := range options {
- fmt.Printf("\033[33m%d. %s\033[0m\n", i+1, option)
- }
-
- for {
- line, err := rl.Readline()
- if err != nil {
- return "", err
- }
-
- trimmed := strings.TrimSpace(line)
- switch trimmed {
- case "1":
- return "Local", nil
- case "2":
- return "OBS", nil
- case "3":
- return "OSS", nil
- case "4":
- return "COS", nil
- case "5":
- return "EFile", nil
- case "6":
- return "S3", nil
- default:
- fmt.Printf("\033[31m错误: 无效选项 '%s',请输入序号!\033[0m\n", line)
- }
- }
- }
-
- func (userSpace *MyUserSpace) collectLocalConfig(rl *readline.Instance) error {
- var err error
- rl.SetPrompt("\033[36m请输入StorageName: \033[0m")
- storageName, err := rl.Readline()
- if err != nil {
- return err
- }
-
- rl.SetPrompt("\033[36m请输入Location: \033[0m")
- location, err := rl.Readline()
- if err != nil {
- return err
- }
-
- rl.SetPrompt("\033[36m请输入RootDir: \033[0m")
- rootDir, err := rl.Readline()
- if err != nil {
- return err
- }
-
- userSpace.Storage = &cortypes.LocalType{
- Type: "Local",
- Location: cortypes.Location{
- StorageName: storageName,
- Location: location,
- },
- }
- userSpace.Credential = &cortypes.LocalCred{
- Type: "Local",
- RootDir: rootDir,
- }
- return nil
- }
-
- func (userSpace *MyUserSpace) collectObsConfig(rl *readline.Instance) error {
- var err error
- rl.SetPrompt("\033[36m请输入Region: \033[0m")
- region, err := rl.Readline()
- if err != nil {
- return err
- }
-
- rl.SetPrompt("\033[36m请输入Endpoint: \033[0m")
- endpoint, err := rl.Readline()
- if err != nil {
- return err
- }
-
- rl.SetPrompt("\033[36m请输入Bucket: \033[0m")
- bucket, err := rl.Readline()
- if err != nil {
- return err
- }
-
- rl.SetPrompt("\033[36m请输入ProjectID: \033[0m")
- projectID, err := rl.Readline()
- if err != nil {
- return err
- }
-
- rl.SetPrompt("\033[36m请输入AccessKeyID: \033[0m")
- accessKey, err := rl.Readline()
- if err != nil {
- return err
- }
-
- secretBytes, err := rl.ReadPassword("\033[36m请输入AccessKeySecret: \033[0m")
- if err != nil {
- return err
- }
- secretKey := string(secretBytes)
-
- userSpace.Storage = &cortypes.OBSType{
- Type: "OBS",
- Region: region,
- Endpoint: endpoint,
- Bucket: bucket,
- ProjectID: projectID,
- }
- userSpace.Credential = &cortypes.OBSCred{
- Type: "OBS",
- AK: accessKey,
- SK: secretKey,
- }
-
- for {
- rl.SetPrompt("\033[36m是否支持存储服务间直传文件?(y/n): \033[0m")
- input, err := rl.Readline()
- if err != nil {
- return err
- }
-
- switch strings.ToLower(strings.TrimSpace(input)) {
- case "y", "yes":
- userSpace.Features = append(userSpace.Features, &cortypes.S2STransferFeature{
- Type: "S2STransfer",
- })
- return nil
- case "n", "no":
- fmt.Println("\033[36m不支持存储服务间直传文件 \033[0m")
- return nil
- default:
- fmt.Println("\033[31m无效输入!请输入 y/n 或 yes/no \033[0m")
- }
- }
- }
-
- func (userSpace *MyUserSpace) collectOssConfig(rl *readline.Instance) error {
- var err error
- rl.SetPrompt("\033[36m请输入Region: \033[0m")
- region, err := rl.Readline()
- if err != nil {
- return err
- }
-
- rl.SetPrompt("\033[36m请输入Endpoint: \033[0m")
- endpoint, err := rl.Readline()
- if err != nil {
- return err
- }
-
- rl.SetPrompt("\033[36m请输入Bucket: \033[0m")
- bucket, err := rl.Readline()
- if err != nil {
- return err
- }
-
- rl.SetPrompt("\033[36m请输入AccessKeyID: \033[0m")
- accessKey, err := rl.Readline()
- if err != nil {
- return err
- }
-
- secretBytes, err := rl.ReadPassword("\033[36m请输入AccessKeySecret: \033[0m")
- if err != nil {
- return err
- }
- secretKey := string(secretBytes)
-
- userSpace.Storage = &cortypes.OSSType{
- Region: region,
- Endpoint: endpoint,
- Bucket: bucket,
- }
- userSpace.Credential = &cortypes.OSSCred{
- Type: "OSS",
- AK: accessKey,
- SK: secretKey,
- }
- return nil
- }
-
- func (userSpace *MyUserSpace) collectCosConfig(rl *readline.Instance) error {
- var err error
- rl.SetPrompt("\033[36m请输入Region: \033[0m")
- region, err := rl.Readline()
- if err != nil {
- return err
- }
-
- rl.SetPrompt("\033[36m请输入Endpoint: \033[0m")
- endpoint, err := rl.Readline()
- if err != nil {
- return err
- }
-
- rl.SetPrompt("\033[36m请输入Bucket: \033[0m")
- bucket, err := rl.Readline()
- if err != nil {
- return err
- }
-
- rl.SetPrompt("\033[36m请输入AccessKeyID: \033[0m")
- accessKey, err := rl.Readline()
- if err != nil {
- return err
- }
-
- secretBytes, err := rl.ReadPassword("\033[36m请输入AccessKeySecret: \033[0m")
- if err != nil {
- return err
- }
- secretKey := string(secretBytes)
-
- userSpace.Storage = &cortypes.COSType{
- Type: "COS",
- Region: region,
- Endpoint: endpoint,
- Bucket: bucket,
- }
- userSpace.Credential = &cortypes.COSCred{
- Type: "COS",
- AK: accessKey,
- SK: secretKey,
- }
- return nil
- }
-
- func (userSpace *MyUserSpace) collectEfileConfig(rl *readline.Instance) error {
- var err error
- rl.SetPrompt("\033[36m请输入ClusterID: \033[0m")
- clusterID, err := rl.Readline()
- if err != nil {
- return err
- }
-
- rl.SetPrompt("\033[36m请输入TokenURL: \033[0m")
- tokenURL, err := rl.Readline()
- if err != nil {
- return err
- }
-
- rl.SetPrompt("\033[36m请输入APIURL: \033[0m")
- apiURL, err := rl.Readline()
- if err != nil {
- return err
- }
-
- tokenExpire := 0
- for {
- rl.SetPrompt("\033[36m请输入TokenExpire: \033[0m")
- valueInt, err := rl.Readline()
- if err != nil {
- return err
- }
- if strings.TrimSpace(valueInt) == "" {
- fmt.Println("\033[31m错误:输入不能为空,请输入正整数\033[0m")
- continue
- }
- num, err := strconv.ParseInt(valueInt, 10, 64)
- if err != nil {
- fmt.Printf("\033[31m错误:'%s' 不是有效整数,请输入正整数\033[0m\n", valueInt)
- continue
- }
- if num <= 0 {
- fmt.Printf("\033[31m错误:%d 不是正整数,请输入大于 0 的整数\033[0m\n", num)
- continue
- }
- tokenExpire = int(num)
- break
- }
-
- rl.SetPrompt("\033[36m请输入User: \033[0m")
- user, err := rl.Readline()
- if err != nil {
- return err
- }
-
- passwordBytes, err := rl.ReadPassword("\033[36m请输入Password: \033[0m")
- if err != nil {
- return err
- }
- password := string(passwordBytes)
-
- rl.SetPrompt("\033[36m请输入OrgID: \033[0m")
- orgID, err := rl.Readline()
- if err != nil {
- return err
- }
-
- userSpace.Storage = &cortypes.EFileType{
- Type: "EFile",
- ClusterID: clusterID,
- }
- userSpace.Credential = &cortypes.EFileCred{
- Type: "EFile",
- TokenURL: tokenURL,
- APIURL: apiURL,
- TokenExpire: tokenExpire,
- User: user,
- Password: password,
- OrgID: orgID,
- }
-
- for {
- rl.SetPrompt("\033[36m是否提供能进行EC计算的接口?(y/n): \033[0m")
- input, err := rl.Readline()
- if err != nil {
- return err
- }
-
- switch strings.ToLower(strings.TrimSpace(input)) {
- case "y", "yes":
- userSpace.Features = append(userSpace.Features, &cortypes.ECMultiplierFeature{
- Type: "ECMultiplier",
- })
- return nil
- case "n", "no":
- fmt.Println("\033[36m未提供能进行EC计算的接口 \033[0m")
- return nil
- default:
- fmt.Println("\033[31m无效输入!请输入 y/n 或 yes/no \033[0m")
- }
- }
- }
-
- func (userSpace *MyUserSpace) collectS3Config(rl *readline.Instance) error {
- var err error
- rl.SetPrompt("\033[36m请输入Region: \033[0m")
- region, err := rl.Readline()
- if err != nil {
- return err
- }
-
- rl.SetPrompt("\033[36m请输入Endpoint: \033[0m")
- endpoint, err := rl.Readline()
- if err != nil {
- return err
- }
-
- rl.SetPrompt("\033[36m请输入Bucket: \033[0m")
- bucket, err := rl.Readline()
- if err != nil {
- return err
- }
-
- rl.SetPrompt("\033[36m请输入AccessKeyID: \033[0m")
- accessKey, err := rl.Readline()
- if err != nil {
- return err
- }
-
- secretBytes, err := rl.ReadPassword("\033[36m请输入AccessKeySecret: \033[0m")
- if err != nil {
- return err
- }
- secretKey := string(secretBytes)
-
- userSpace.Storage = &cortypes.S3Type{
- Type: "S3",
- Region: region,
- Endpoint: endpoint,
- Bucket: bucket,
- }
- userSpace.Credential = &cortypes.S3Cred{
- Type: "S3",
- AK: accessKey,
- SK: secretKey,
- }
-
- for {
- rl.SetPrompt("\033[36m是否支持分段上传?(y/n): \033[0m")
- input, err := rl.Readline()
- if err != nil {
- return err
- }
-
- switch strings.ToLower(strings.TrimSpace(input)) {
- case "y", "yes":
- userSpace.Features = append(userSpace.Features, &cortypes.MultipartUploadFeature{
- Type: "MultipartUpload",
- })
- return nil
- case "n", "no":
- fmt.Println("\033[36m不支持分段上传 \033[0m")
- return nil
- default:
- fmt.Println("\033[31m无效输入!请输入 y/n 或 yes/no \033[0m")
- }
- }
- }
-
- func (userSpace *MyUserSpace) collectShardStore(rl *readline.Instance) error {
- for {
- rl.SetPrompt("\033[36m是否开启分片存储功能?(y/n): \033[0m")
- input, err := rl.Readline()
- if err != nil {
- return err
- }
-
- switch strings.ToLower(strings.TrimSpace(input)) {
- case "y", "yes":
- for {
- rl.SetPrompt("\033[36m请输入最大Size: \033[0m")
- sizeInput, err := rl.Readline()
- if err != nil {
- return err
- }
- if strings.TrimSpace(sizeInput) == "" {
- fmt.Println("\033[31m错误:输入不能为空31m错误:输入不能为空,请输入正整数\033[0m")
- continue
- }
-
- maxSize, err := strconv.ParseInt(sizeInput, 10, 64)
- if err != nil {
- fmt.Printf("\033[31m错误:'%s' 不是有效整数,请输入正整数\033[0m\n", sizeInput)
- continue
- }
- if maxSize <= 0 {
- fmt.Printf("\033[31m错误:%d 不是正整数,请输入大于 0 的整数\033[0m\n", maxSize)
- continue
- }
- userSpace.ShardStore = &cortypes.ShardStoreUserConfig{
- MaxSize: maxSize,
- }
- return nil
- }
-
- case "n", "no":
- fmt.Println("\033[31m分片存储未启用 \033[0m")
- return nil
- default:
- fmt.Println("\033[31m无效输入!请输入 y/n 或 yes/no \033[0m")
- }
- }
- }
-
- func (userSpace *MyUserSpace) collectWorkingDir(rl *readline.Instance) error {
- for {
- rl.SetPrompt("\033[36m默认工作路径(WorkingDir)为jcs,是否修改?(y/n): \033[0m")
- input, err := rl.Readline()
- if err != nil {
- return err
- }
-
- switch strings.ToLower(strings.TrimSpace(input)) {
- case "y", "yes":
- rl.SetPrompt("\033[36m请输入新的工作路径(WorkingDir): \033[0m")
- newValue, err := rl.Readline()
- if err != nil {
- return err
- }
- if newValue != "" {
- userSpace.WorkingDir = newValue
- }
- return nil
- case "n", "no":
- userSpace.WorkingDir = "jcs"
- return nil
- default:
- fmt.Println("\033[31m无效输入!请输入 y/n 或 yes/no \033[0m")
- }
- }
- }
|