怎样在 Go 中使用 Vultr 对象存储

介绍

Vultr 对象存储是一种高度可扩展、与 S3 兼容的云对象存储解决方案,用于存储文件或对象。 本指南解释了怎样在 Go 中使用 Vultr 对象存储 GoVultr v2,以及怎样使用适用于 Go 的 AWS 开发工具包管理对象存储中的存储桶。

先决条件

你会需要:

  • 在 Linux、Windows 或 macOS 上运行的计算机工作站
  • 安装在您的计算机工作站上的最新版本的 Go

这些示例使用 Linux $ 提示,但这些命令也适用于 Mac 和 Windows。

使用 Go 管理 Vultr 对象存储

  1. 生成一个 API 密钥 从你的 API 设置 经过 启用您的 API.

    警告:确保您的 API 密钥安全。 您的 API 密钥可以访问您的整个 Vultr 帐户,公开公开您的 API 密钥可能会危及您的帐户。

  2. 创建一个新的项目文件夹。

    $ mkdir ObjectStorage
    
  3. 将目录更改为新文件夹。

    $ cd ObjectStorage
    
  4. 初始化模块。

    $ go mod init ObjectStorage
    
  5. 安装 GoVultr v2.

    $ go get -u github.com/vultr/govultr/v2
    
  6. 安装 oAuth2 for Go.

    $ go get golang.org/x/oauth2
    
  7. 将您的 API 密钥设置为环境变量。 代替 YOUR-API-KEY-HERE 使用您的 API 密钥在您的 API 设置.

    Linux 和 macOS 工作站运行:

    $ export VULTR_API_KEY=YOUR-API-KEY-HERE
    

    Windows 工作站运行:

    C:\> setx VULTR_API_KEY "YOUR-API-KEY-HERE"
    
  8. 使用您喜欢的纯文本编辑器创建和编辑 main.go. Linux 用户可以使用 nano而 Mac 和 Windows 用户可能会选择 TextEdit 或者 Notepad.

    $ nano main.go
    
  9. 将以下代码粘贴到 main.go,它设置了 main 打包并导入所有需要的包。

    package main
    
    import (
        "bufio"
         "context"
         "fmt"
         "log"
         "os"
         "strings"
         "time"
    
         "github.com/vultr/govultr/v2"
         "golang.org/x/oauth2"
    )
    
  10. 将以下代码粘贴到 main.go,它声明了全局变量。

    var (
         apiKey       = os.Getenv("VULTR_API_KEY")
         vc           *govultr.Client
         ctx          = context.Background()
         input        int
         input2       string
         loop         string
         objStorageID string
    )
    
  11. 将以下代码粘贴到 main.go初始化 oAuth2 配置, 代币来源Vultr 客户端.

    func init() {
        config := &oauth2.Config{}
        ts := config.TokenSource(ctx, &oauth2.Token{AccessToken: apiKey})
        vc = govultr.NewClient(oauth2.NewClient(ctx, ts))
    }
    

使用 GoVultr 进行对象存储管理

填充你的 main.go 每个函数的文件。 每个函数都针对特定的对象存储操作。

函数:listClusters()

此函数列出所有对象存储集群。 如果列出集群时出现错误或没有找到集群,它会停止程序。

func listClusters() {
     clusterList, meta, err := vc.ObjectStorage.ListCluster(ctx, nil)
     if err != nil {
          log.Panicf("Error listing clusters: %s", err)
     }
     if meta.Total <= 0 {
          log.Panic("There are no clusters found to create an Object Storage.")
     }
     log.Printf("List of All Clusters: %+v", clusterList)
}

函数:createObjStorage()

此函数在您选择的集群中创建一个对象存储,然后在它变为 积极的. 如果在创建对象存储时出现任何错误,它会停止程序。

本指南使用 ClusterID 2,这是 Vultr 的新泽西对象存储位置, ewr1.vultrobjects.com.

func createObjStorage() {
     var objStorageName string
     clusterID := 2
     fmt.Print("Enter Your Desired Object Storage Name: ")
     scanner := bufio.NewScanner(os.Stdin)
     for scanner.Scan() {
          objStorageName = scanner.Text()
          fmt.Print()
          if objStorageName != "" {
               break
          }
     }
     objStorageNew, errn := vc.ObjectStorage.Create(ctx, clusterID, objStorageName)
     if errn != nil {
          log.Panicf("Error creating storage: %s", errn)
     } else {
          log.Printf("Succesfully created an Object Storage with ID: %s", objStorageNew.ID)
     }
     for {
          objStorageNewInfo, erri := vc.ObjectStorage.Get(ctx, objStorageNew.ID)
          if erri != nil {
               log.Panicf("Error getting Object Storage Information: %s", erri)
          }
          if objStorageNewInfo.Status == "active" {
               log.Print("Your Object Storage is now Active.")
               log.Printf("Object Storage Information: %+v", objStorageNewInfo)
               log.Println("S3 Credentials: ")
               log.Printf("Hostname: %s | Access Key: %s | Secret Key: %s", objStorageNewInfo.S3Hostname, objStorageNewInfo.S3AccessKey, objStorageNewInfo.S3SecretKey)
               break
          }
          log.Printf("The Object Storage is currently %s. Waiting another ten seconds until it becomes active.", objStorageNewInfo.Status)
          time.Sleep(time.Second * 10)
     }
}

该功能需要一个用户输入:用户想要的对象存储名称。 然后它会创建新的对象存储并每十秒检查一次新创建的对象存储的状态,直到它变为活动状态。 在对象存储的状态变为活动状态后,它会显示其完整信息。

函数:listObjStorage1() 和 listObjStorage2()

这些函数列出了您帐户中的所有对象存储。 有两种方法可以显示您的对象存储信息。

首先:将所有对象存储一一列出,然后以JSON格式显示数据。

func listObjStorage1() {
     objStorageList, meta, err := vc.ObjectStorage.List(ctx, nil)
     log.Printf("The Total Number of Object Storage: %d", meta.Total)
     for x := 0; x != len(objStorageList); x++ {
          log.Printf("Object Storage #%d:", x+1)
          log.Printf("List of Object Storage: %+v", objStorageList[x])
          log.Println()
     }
     if err != nil {
          log.Panicf("Error listing Object Storage: %s", err)
     }
}

此功能以 JSON 格式显示您帐户中的活动对象存储总数及其完整信息。

第二:将所有对象存储一一列出,然后以键值对的形式展示每个对象存储的数据。

func listObjStorage2() {
     objStorageList, meta, err := vc.ObjectStorage.List(ctx, nil)
     log.Printf("The Total Number of Object Storage: %d", meta.Total)
     for x := 0; x != len(objStorageList); x++ {
          log.Printf("Object Storage #%d:", x+1)
          log.Printf("Date Created: %s", objStorageList[x].DateCreated)
          log.Printf("Object Storage ID: %s", objStorageList[x].ID)
          log.Printf("Object Storage Label: %s", objStorageList[x].Label)
          log.Printf("Object Storage Location: %s", objStorageList[x].Location)
          log.Printf("Object Storage Region: %s", objStorageList[x].Region)
          log.Printf("Object Storage Hostname: %s", objStorageList[x].S3Hostname)
          log.Printf("Object Storage Access Key: %s", objStorageList[x].S3AccessKey)
          log.Printf("Object Storage Secret Key: %s", objStorageList[x].S3SecretKey)
          log.Printf("Object Storage Status: %s", objStorageList[x].Status)
          log.Printf("Object Storage Cluster ID: %d", objStorageList[x].ObjectStoreClusterID)
          log.Println()
     }
     if err != nil {
          log.Panicf("Error listing Object Storage: %s", err)
     }
}

此功能显示您帐户中的活动对象存储总数及其完整信息。 这 对象存储的 ID 当您要操作对象存储时需要。

函数:getObjStorage()

此功能显示特定对象存储的完整信息或在获取对象存储信息时出现错误停止程序。

func getObjStorage() {
     fmt.Println("To Get your Object Storage's ID, List all of your Object Storage.")
     fmt.Print("Enter Your Object Storage's ID to get its Full Information (e.g. cb676a46-66fd-4dfb-b839-443f2e6c0b60): ")
     fmt.Scan(&objStorageID)
     objStorageGet, err := vc.ObjectStorage.Get(ctx, objStorageID)
     log.Printf("Full information of Object Storage with an ID \"%s\".", objStorageID)
     log.Printf("Object Storage ID: %s", objStorageGet.ID)
     log.Printf("Date Created: %s", objStorageGet.DateCreated)
     log.Printf("Label: %s", objStorageGet.Label)
     log.Printf("Location: %s", objStorageGet.Location)
     log.Printf("Region: %s", objStorageGet.Region)
     log.Printf("S3 Hostname: %s", objStorageGet.S3Hostname)
     log.Printf("S3 Access Key: %s", objStorageGet.S3AccessKey)
     log.Printf("S3 Secret Key: %s", objStorageGet.S3SecretKey)
     log.Printf("Status: %s", objStorageGet.Status)
     log.Printf("Cluster ID: %d", objStorageGet.ObjectStoreClusterID)
     log.Println()
     if err != nil {
          log.Panicf("Error Getting Object Storage that has an ID %s: %s", objStorageID, err)
     }
}

此功能需要一个用户输入:您的对象存储的 ID,您可以在列出所有对象存储时找到它。

函数:delObjStorage()

此函数删除特定对象存储。

func delObjStorage() {
     fmt.Println("To Get your Object Storage's ID, List all of your Object Storage.")
     fmt.Print("Enter the ID of the Object Storage that you want to Delete (e.g. cb676a46-66fd-4dfb-b839-443f2e6c0b60): ")
     fmt.Scan(&objStorageID)
     objStorageDel := vc.ObjectStorage.Delete(ctx, objStorageID)
     if objStorageDel == nil {
          log.Printf("Successfully deleted object storage with an ID \"%s\"", objStorageID)
     }
}

此功能需要一个用户输入:您要删除的对象存储的 ID。

函数:updateObjectStorage()

此函数更新或更改特定对象存储的标签。

func updateObjectStorage() {
     var newLabel string
     fmt.Println("To Get your Object Storage's ID, List all of your Object Storage.")
     fmt.Print("Enter the ID of the Object Storage that you want to Update the Label (e.g. cb676a46-66fd-4dfb-b839-443f2e6c0b60): ")
     fmt.Scan(&objStorageID)
     fmt.Print("Enter Your Desired New Object Storage Label: ")
     scanner := bufio.NewScanner(os.Stdin)
     for scanner.Scan() {
          newLabel = scanner.Text()
          fmt.Print()
          if newLabel != "" {
               break
          }
     }
     objStorageUpdate := vc.ObjectStorage.Update(ctx, objStorageID, newLabel)
     if objStorageUpdate == nil {
          log.Printf("Succesfully updated the label of the object storage with an ID of: \"%s\"", objStorageID)
     }
     fmt.Print()
}

此功能需要两个用户输入:您的对象存储 ID,您可以在列出所有对象存储时找到它,以及您首选的新对象存储标签。

函数 regenKeys()

此函数将重新生成特定对象存储的新 Access Key 和 Secret Key。

func regenKeys() {
     fmt.Println("To Get your Object Storage's ID, List all of your Object Storage.")
     fmt.Print("Enter the ID of the Object Storage that you want to Regenerate Keys (e.g. cb676a46-66fd-4dfb-b839-443f2e6c0b60): ")
     fmt.Scan(&objStorageID)
     objStorageNewKeys, err := vc.ObjectStorage.RegenerateKeys(ctx, objStorageID)
     log.Print("Successfully Regenerated new S3 Credentials.")
     log.Printf("Your Object Storage's New S3 Credentials are: %v", objStorageNewKeys)
     log.Printf("S3 Hostname: %s", objStorageNewKeys.S3Hostname)
     log.Printf("S3 Access Key: %s", objStorageNewKeys.S3AccessKey)
     log.Printf("S3 Secret Key: %s", objStorageNewKeys.S3SecretKey)
     if err != nil {
          log.Panicf("Error Regenerating New S3 Credentials: %v", err)
     }
}

此功能需要一个用户输入:您要重新生成密钥的对象存储的 ID。

主功能

该函数询问用户他们想要执行什么对象存储操作,然后根据用户输入调用特定函数。

func main() {
     for {
          fmt.Println("Input '1' to List All Object Storage Clusters.")
          fmt.Println("Input '2' to Create an Object Storage.")
          fmt.Println("Input '3' to List All Object Storage (Less Organized).")
          fmt.Println("Input '4' to List All Object Storage (More Organized).")
          fmt.Println("Input '5' to Get the Full Information of your Object Storage.")
          fmt.Println("Input '6' to Delete an Object Storage.")
          fmt.Println("Input '7' to Update an Object Storage's Label.")
          fmt.Println("Input '8' to Regenerate Access Key and Secret Key of your Object Storage.")
          fmt.Print("Your Input: ")
          fmt.Scan(&input)
          switch input {
          case 1:
               listClusters()
          case 2:
               createObjStorage()
          case 3:
               listObjStorage1()
          case 4:
               listObjStorage2()
          case 5:
               getObjStorage()
          case 6:
               delObjStorage()
          case 7:
               updateObjectStorage()
          case 8:
               regenKeys()
          default:
               fmt.Println("Invalid Input! Please try again.")
               continue
          }

          fmt.Print("Do you want to rerun the program? (y/n): ")
          fmt.Scan(&input2)
          loop = strings.ToLower(input2)
          if loop == "n" {
               fmt.Println("Closing the Program...")
               time.Sleep(2 * time.Second)
               break
          } else if loop == "y" {
               continue
          } else {
               log.Fatal("Invalid Input! Closing the Program.")
               time.Sleep(2 * time.Second)
          }
     }
}

构建对象存储项目

填充后 main.go 文件与 example 代码,保存和 close 文件。 然后,将代码编译成二进制可执行文件。

$ go build

运行可执行文件,然后选择您要执行的对象存储操作。

$ ./ObjectStorage

桶操作

要管理您的存储桶,请使用 适用于 Go 的 AWS 开发工具包.

设置 Bucket 项目环境

  1. 创建一个新的项目文件夹。

    $ mkdir Bucket
    
  2. 将目录更改为新文件夹。

    $ cd Bucket
    
  3. 初始化模块。

    $ go mod init Bucket
    
  4. 安装 适用于 Go 的 AWS 开发工具包.

    $ go get github.com/aws/aws-sdk-go
    
  5. 安装 模仿类型. 该包用于设置要上传的每个文件的 Content-Type。

    $ go get github.com/gabriel-vasile/mimetype
    
  6. 获取您的对象存储的访问密钥和秘密密钥 Vultr 的网站,或使用 ObjectStorage 上面的程序。

  7. 将您的对象存储的访问密钥和秘密密钥设置为环境变量。 代替 YOUR-ACCESS-KEY-HEREYOUR-SECRET-KEY-HERE 使用您的对象存储的访问密钥和秘密密钥。

    Linux 和 macOS 工作站运行:

    $ export ACCESS_KEY=YOUR-ACCESS-KEY-HERE
    $ export SECRET_KEY=YOUR-SECRET-KEY-HERE
    

    Windows 工作站运行:

    C:\> setx ACCESS_KEY "YOUR-ACCESS-KEY-HERE"
    C:\> setx SECRET_KEY "YOUR-SECRET-KEY-HERE"
    
  8. 使用您喜欢的纯文本编辑器创建和编辑 main.go. Linux 用户可以使用 nano而 Mac 和 Windows 用户可能会选择 TextEdit 或者 Notepad.

    $ nano main.go
    
  9. 将以下代码粘贴到 main.go,它设置了 main 打包并导入所有需要的包。

    package main
    
    import (
         "fmt"
         "io/ioutil"
         "log"
         "os"
         "path"
         "regexp"
         "strings"
         "time"
    
         "github.com/aws/aws-sdk-go/aws"
         "github.com/aws/aws-sdk-go/aws/awserr"
         "github.com/aws/aws-sdk-go/aws/credentials"
         "github.com/aws/aws-sdk-go/aws/session"
         "github.com/aws/aws-sdk-go/service/s3"
         "github.com/gabriel-vasile/mimetype"
    )
    
  10. 将以下代码粘贴到 main.go,它声明了全局变量。

    var (
         s3Vultr    *s3.S3
         accessKey  = os.Getenv("ACCESS_KEY")
         secretKey  = os.Getenv("SECRET_KEY")
         bucketName string
         directory  string
         filename   string
         input      int
         input2     string
         loop       string
    )
    
  11. 将以下代码粘贴到 main.go,它初始化 Vultr S3 会话。

    func init() {
        s3Vultr = s3.New(session.Must(session.NewSession(&aws.Config{
            Region:      aws.String("ewr"),
            Credentials: credentials.NewStaticCredentials(accessKey, secretKey, ""),
            Endpoint:    aws.String("https://ewr1.vultrobjects.com/"),
        })))
    }
    

使用适用于 Go 的 AWS 开发工具包的存储桶操作

填充你的 main.go 每个函数的文件。 每个函数都针对特定的存储桶操作。

函数:listAllBuckets()

此函数列出对象存储中的所有存储桶。

func listAllBuckets() (ret *s3.ListBucketsOutput) {
     ret, err := s3Vultr.ListBuckets(&s3.ListBucketsInput{})
     if err != nil {
          panic(err)
     }
     return ret
}

函数:createBucket()

这个函数有两个辅助函数, nameCheck()newBucket(). 它会在您的对象存储中创建一个存储桶,如果存储桶名称已存在,则停止程序。 它需要一个用户输入:您的存储桶的首选名称。 如果您输入的存储桶名称不符合存储桶命名条件,它会要求您重新输入另一个存储桶名称。

func nameCheck(str string) bool {
     checker := regexp.MustCompile(`^[a-z0-9-]*$`).MatchString(str)
     alphanumeric := "abcdefghijklmnopqrstuvwxyz1234567890"
     if checker && strings.Contains(alphanumeric, string(str[0])) && len(str) >= 3 && len(str) <= 63 {
          return true
     } else {
          return false
     }
}

func newBucket() (ret *s3.CreateBucketOutput) {
     _, err := s3Vultr.CreateBucket(&s3.CreateBucketInput{
          Bucket: aws.String(bucketName),
          CreateBucketConfiguration: &s3.CreateBucketConfiguration{
               LocationConstraint: aws.String(""),
          },
     })
     if awsError, ok := err.(awserr.Error); ok {
          if awsError.Code() == s3.ErrCodeBucketAlreadyExists {
               log.Fatalf("Bucket %q already exists. Error: %v", bucketName, awsError.Code())
          }
     } else {
          log.Printf("Successfully created bucket %q", bucketName)
     }
     return ret
}

func createBucket() (ret *s3.CreateBucketOutput) {
     for {
          fmt.Println("Bucket names are unique to their location and must meet the following criteria:")
          fmt.Println("Only lowercase and starts with a letter or number. No spaces.")
          fmt.Println("Bucket name may contain dashes")
          fmt.Println("Must be between 3 and 63 characters long.")
          fmt.Print("Enter your preferred Name for the Bucket: ")
          fmt.Scan(&bucketName)
          if nameCheck(bucketName) {
               break
          } else {
               fmt.Printf("%q does not meet the criteria above. Please try again.", bucketName)
               fmt.Print("\n\n")
               continue
          }
     }
     bucketList := listAllBuckets()
     if len(bucketList.Buckets) != 0 {
          for _, bucket := range bucketList.Buckets {
               if bucketName == *bucket.Name {
                    log.Fatalf("Bucket %q already exists and is owned by you.", bucketName)
               } else {
                    newBucket()
                    break
               }
          }
     } else {
          newBucket()
     }
     return ret
}

createBucket() 函数检查您的输入存储桶名称是否已经存在并且归您所有,然后它调用 nameCheck() 功能和 newBucket() 功能。

nameCheck() 函数检查用户输入的存储桶名称,看它是否符合命名存储桶的条件,并再次询问是否不符合。 它使用 regexp 包检查输入是否仅包含小写字母、数字和破折号。 要检查输入是否以字母或数字开头,它使用 strings 包的 strings.Contains(). 它还检查输入长度是否在 3 到 63 个字符之间。

newBucket() 如果输入的存储桶名称不存在,函数会尝试创建一个新存储桶,否则返回错误。

函数:uploadObject()

此函数将文件或对象上传到特定存储桶。 它需要三个用户输入:您要存储文件的存储桶名称,您要将文件放入存储桶的路径或目录,最后是您要上传的文件的路径。

func uploadObject() (ret *s3.PutObjectOutput) {
     fmt.Print("Enter the name of the bucket where you want to upload the File/Object: ")
     fmt.Scan(&bucketName)
     fmt.Print("Enter the Path or Directory where you want to upload the File/Object in the bucket: (e.g., assets/css/): ")
     fmt.Scan(&directory)
     fmt.Print("Enter the Path to the file that you want to upload (e.g., css/styles.css): ")
     fmt.Scan(&filename)

     f, err := os.Open(filename)
     if err != nil {
          panic(err)
     }
     var mtype2 string
     if strings.Contains(filename, ".css") {
          mtype2 = "text/css"
     } else {
          mtype, errmime := mimetype.DetectFile(filename)
          if errmime != nil {
               log.Fatalf("Error getting Content-Type: %v", errmime)
          }
          mtype2 = mtype.String()
     }

     log.Println("Uploading Object:", filename)
     ret, err = s3Vultr.PutObject(&s3.PutObjectInput{
          Body:        f,
          Bucket:      aws.String(bucketName),
          Key:         aws.String(path.Join(directory, strings.Split(filename, "https://www.vultr.com/")[strings.Count(filename, "https://www.vultr.com/")])),
          ACL:         aws.String("public-read"),
          ContentType: aws.String(mtype2),
     })

     if err != nil {
          panic(err)
     } else {
          log.Printf("File %q was Uploaded Successfully.", filename)
     }
     return ret
}

你的文件 预设访问控制列表 (ACL) 被设定为 私人的 默认情况下,这意味着除了您之外没有人可以访问它。 要适当地提供文件,您必须 授予公共读取权限 并正确设置文件的内容类型。 场 ACL 与价值 public-read 授予所有用户 访问和所有者 完全控制. 当您将文件上传到存储桶时,默认的内容类型通常是 application/octet-stream. 为了自动设置文件的内容类型,程序使用 模仿类型 包来检测每个文件的 MIME 类型或内容类型. 看 此支持的 MIME 类型列表 供你参考。 请注意 CSS 不在支持的 MIME 类型列表中,因此使用 strings.Contains(). 如果文件名有 .css 扩展,它将内容类型设置为 text/css.

函数:listObjects()

此函数列出存储桶中的所有文件或对象。 它需要一个用户输入:存储桶的名称来列出其文件。

func listObjects() (ret *s3.ListObjectsV2Output) {
     fmt.Print("Enter the name of the bucket to list its file/s: ")
     fmt.Scan(&bucketName)
     ret, err := s3Vultr.ListObjectsV2(&s3.ListObjectsV2Input{
          Bucket: aws.String(bucketName),
     })

     if err != nil {
          panic(err)
     }
     return ret
}

函数:getObject()

此函数将存储桶中的文件或对象下载到您的文件所在的同一目录中 main.go 或二进制可执行文件是。 它需要三个用户输入:存储桶名称、文件的目录或路径以及要下载的文件的名称。

func getObject() {
     fmt.Print("Enter the name of the bucket that contains the file that you want to download: ")
     fmt.Scan(&bucketName)
     fmt.Print("Enter the Path or Directory of the file (e.g. assets/css/): ")
     fmt.Scan(&directory)
     fmt.Print("Enter the name of the file that you want to download(e.g., styles.css): ")
     fmt.Scan(&filename)
     log.Println("Downloading: ", filename)

     ret, err := s3Vultr.GetObject(&s3.GetObjectInput{
          Bucket: aws.String(bucketName),
          Key:    aws.String(path.Join(directory, strings.Split(filename, "https://www.vultr.com/")[strings.Count(filename, "https://www.vultr.com/")])),
     })

     if err != nil {
          panic(err)
     }

     body, _ := ioutil.ReadAll(ret.Body)
     err = ioutil.WriteFile(filename, body, 0644)
     if err != nil {
          panic(err)
     }
     log.Println("File Downloaded Successfully.")
}

此函数使用读取存储桶内的文件 ioutil.ReadAll(),然后使用写入返回的数据 ioutil.WriteFile(). 它将文件保存为 filename,有一个 644 许可,这意味着所有者拥有 读和写 访问,而组和其他人只有 使用权。

函数:删除对象()

此函数从存储桶中删除文件或对象。 它需要三个用户输入:包含要删除的文件的存储桶的名称、存储桶中文件的路径或目录以及要删除的文件的名称。

func deleteObject() (ret *s3.DeleteObjectOutput) {
     fmt.Print("Enter the name of the bucket that contains the file that you want to delete: ")
     fmt.Scan(&bucketName)
     fmt.Print("Enter the Path or Directory of the file in the bucket (e.g., assets/css/): ")
     fmt.Scan(&directory)
     fmt.Print("Enter the name of the file that you want to delete (e.g., styles.css): ")
     fmt.Scan(&filename)
     log.Println("Deleting: ", filename)
     ret, err := s3Vultr.DeleteObject(&s3.DeleteObjectInput{
          Bucket: aws.String(bucketName),
          Key:    aws.String(path.Join(directory, strings.Split(filename, "https://www.vultr.com/")[strings.Count(filename, "https://www.vultr.com/")])),
     })

     if err != nil {
          panic(err)
     } else {
          log.Printf("%q deleted Successfully", filename)
     }
     return ret
}

函数:deleteAllObjects()

此函数删除存储桶中的所有文件或对象。 它需要一个用户输入: 存储桶名称 你想清空。 当您要删除存储桶时,此功能很有用,因为您必须先删除其所有内容才能删除它。

func deleteAllObjects() {
     fmt.Scan(&bucketName)
     objectList, errList := s3Vultr.ListObjectsV2(&s3.ListObjectsV2Input{
          Bucket: aws.String(bucketName),
     })
     if errList != nil {
          log.Fatalf("Error Listing objects: %v", errList)
     }
     for _, object := range objectList.Contents {
          log.Printf("Deleting %v", *object.Key)
          _, err := s3Vultr.DeleteObject(&s3.DeleteObjectInput{
               Bucket: aws.String(bucketName),
               Key:    aws.String(*object.Key),
          })
          log.Printf("%v Deleted Successfully", *object.Key)
          if err != nil {
               log.Fatalf("Error Deleteing Objects.")
          }
     }
     log.Println("All Files deleted successfully.")
}

该函数首先列出所有桶的内容,然后获取 钥匙 用于删除每个文件的每个对象。

函数:删除桶()

此函数从您的对象存储中删除一个存储桶。 它需要一个用户输入:您要删除的存储桶的名称。

func deleteBucket() (ret *s3.DeleteBucketOutput) {
     deleteAllObjects()
     ret, err := s3Vultr.DeleteBucket(&s3.DeleteBucketInput{
          Bucket: aws.String(bucketName),
     })
     if err != nil {
          if awsError, ok := err.(awserr.Error); ok {
               switch awsError.Code() {
               case s3.ErrCodeNoSuchBucket:
                    log.Fatalf("No Bucket exists with the name '%s'", bucketName)
                    log.Println()
               default:
                    panic(err)
               }
          }
     }
     log.Printf("Bucket %q deleted Successfully.", bucketName)
     return ret
}

该函数调用 deleteAllObjects() 首先删除其所有内容,因为您必须先清空存储桶,然后才能删除它。

桶主要功能

main() 函数询问用户他们想要执行什么存储桶操作,然后根据用户输入调用特定函数。

func main() {
     for {
          fmt.Println("Input '1' to List All Buckets in your Object Storage.")
          fmt.Println("Input '2' to Create a new Bucket.")
          fmt.Println("Input '3' to Delete a Bucket.")
          fmt.Println("Input '4' to Upload a File/Object.")
          fmt.Println("Input '5' to List All Files/Objects inside a Bucket.")
          fmt.Println("Input '6' to Download a File/Object from a Bucket.")
          fmt.Println("Input '7' to Delete a File/Object from a Bucket.")
          fmt.Println("Input '8' to Delete All Files/Objects from a Bucket.")
          fmt.Print("Your Input: ")
          fmt.Scan(&input)
          switch input {
          case 1:
               log.Println(listAllBuckets())
          case 2:
               createBucket()
          case 3:
               fmt.Print("Enter the Name of the Bucket that you want to Delete: ")
               deleteBucket()
          case 4:
               uploadObject()
          case 5:
               log.Println(listObjects())
          case 6:
               getObject()
          case 7:
               deleteObject()
          case 8:
               fmt.Print("Enter the Name of the Bucket that you want to Empty: ")
               deleteAllObjects()
          default:
               log.Println("Invalid Input! Please try again.")
               continue
          }

          fmt.Print("Do you want to rerun the program? (y/n): ")
          fmt.Scan(&input2)
          loop = strings.ToLower(input2)
          if loop == "n" {
               fmt.Println("Closing the Program...")
               time.Sleep(2 * time.Second)
               break
          } else if loop == "y" {
               continue
          } else {
               log.Fatalln("Invalid Input! Closing the Program.")
               time.Sleep(2 * time.Second)
          }
     }
}

构建桶项目

填充后 main.go 文件与 example 代码,保存和 close 文件。 然后,将代码编译成二进制可执行文件。

$ go build

运行可执行文件,然后选择您要执行的存储桶操作。

$ ./Bucket

使用 Vultr 对象存储服务静态文件

您必须做两件重要的事情来使用 Vultr 对象存储服务静态文件。 首先,你必须 授予公共读取权限 对你所有的 静态文件. 其次,你需要 为每个文件设置正确的内容类型,否则当您访问静态文件的 URL 时,您的文件将被下载。

在这 example,您将创建一个示例 HTML 和 CSS 静态文件,并使用 Vultr 对象存储托管它们。

  1. 您将使用相同的项目 Bucket 和相同的可执行文件 Bucket.exe 创建存储桶并上传文件,因为其设置(标准 ACL 和 Content-Type)设置为授予公共读取访问权限并自动设置内容类型。

    $ cd Bucket
    
  2. 创建一个名为的 HTML 文件 index.html.

    $ nano index.html
    
  3. 将此示例 HTML 代码粘贴到您的 index.html 文件,然后保存并退出文件。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <link rel="stylesheet" href="#">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>This is a Sample Static File Hosted with Vultr Object Storage</title>
    </head>
    <body>
        <h1>This is a Heading 1</h1>
        <h2>This is a Heading 2</h2>
        <h3>This is a Heading 3</h3>
        <h4>This is a Heading 4</h4>
        <h5>This is a Heading 5</h5>
        <h6>This is a Heading 6</h6>
        <p>This is a Sample Static File Hosted with Vultr Object Storage.</p>
    </body>
    </html>
    
  4. 创建一个名为的文件夹 css.

  5. 创建一个名为的 CSS 文件 style.css 在 – 的里面 css 文件夹。

    $ nano css/style.css
    
  6. 将此示例 CSS 代码粘贴到您的 style.css 文件,然后保存并退出文件。

    h1 {color: blue;}
    h2 {color: red;}
    h3 {color: green;}
    h4 {background-color: blue;}
    h5 {background-color: red;}
    h6 {background-color: green;}
    
  7. 运行二进制可执行文件 Bucket.exe.

    $ ./Bucket
    
  8. 创建一个新存储桶。 Enter 2 创建一个新的存储桶,然后将存储桶命名为 my-static-hosting 或您喜欢的任何存储桶名称。

    这是示例执行:

    Input '1' to List All Buckets in your Object Storage.
    Input '2' to Create a new Bucket.
    Input '3' to Delete a Bucket.
    Input '4' to Upload a File/Object.
    Input '5' to List All Files/Objects inside a Bucket.
    Input '6' to Download a File/Object from a Bucket.
    Input '7' to Delete a File/Object from a Bucket.
    Input '8' to Delete All Files/Objects from a Bucket.
    Your Input: 2
    Bucket names are unique to their location and must meet the following criteria:
    Only lowercase and starts with a letter or number. No spaces.
    Bucket name may contain dashes
    Must be between 3 and 63 characters long.
    Enter your preferred name for the Bucket: my-static-hosting
    2022/07/29 17:31:45 Successfully created bucket "my-static-hosting"
    Do you want to rerun the program? (y/n): n
    Closing the Program...
    
  9. 上传您的 index.html 文件和 style.css 文件。 跑 Bucket.exe 再次,然后输入 4 上传文件。 出现提示时重新运行程序,因为您必须上传两个文件。

    这是示例程序执行:

    $ ./Bucket
    
    Input '1' to List All Buckets in your Object Storage.
    Input '2' to Create a new Bucket.
    Input '3' to Delete a Bucket.
    Input '4' to Upload a File/Object.
    Input '5' to List All Files/Objects inside a Bucket.
    Input '6' to Download a File/Object from a Bucket.
    Input '7' to Delete a File/Object from a Bucket.
    Input '8' to Delete All Files/Objects from a Bucket.
    Your Input: 4
    Enter the name of the bucket where you want to upload the File/Object: my-static-hosting
    Enter the Path or Directory where you want to upload the File/Object in the bucket: (e.g., assets/css/): /
    Enter the Path to the file that you want to upload (e.g., css/styles.css): index.html
    2022/07/29 17:36:03 Uploading Object: index.html
    2022/07/29 17:36:04 File "index.html" was Uploaded Successfully.
    Do you want to rerun the program? (y/n): y
    Input '1' to List All Buckets in your Object Storage.
    Input '2' to Create a new Bucket.
    Input '3' to Delete a Bucket.
    Input '4' to Upload a File/Object.
    Input '5' to List All Files/Objects inside a Bucket.
    Input '6' to Download a File/Object from a Bucket.
    Input '7' to Delete a File/Object from a Bucket.
    Input '8' to Delete All Files/Objects from a Bucket.
    Your Input: 4
    Enter the name of the bucket where you want to upload the File/Object: my-static-hosting
    Enter the Path or Directory where you want to upload the File/Object in the bucket: (e.g., assets/css/): css/
    Enter the Path to the file that you want to upload (e.g., css/styles.css): css/style.css
    2022/07/29 17:36:16 Uploading Object: css/style.css
    2022/07/29 17:36:17 File "css/style.css" was Uploaded Successfully.
    Do you want to rerun the program? (y/n): n
    Closing the Program...
    
  10. 在您的网络浏览器中,导航到 https://bucketname.ewr1.vultrobjects.com/filename. 为了 example, https://my-static-hosting.ewr1.vultrobjects.com/index.html.

  11. 请注意,当您访问文件的 URL 时,会显示您的 HTML 静态文件而不是下载该文件。 链接的 CSS 样式表也被应用。
  12. 您可以上传其他媒体类型,例如图像、视频等,以进一步测试使用 Vultr 对象存储服务静态文件。

更多信息

要了解有关 Vultr 对象存储、GoVultr V2、Vultr API v2 和 AWS SDK for Go 的更多信息,请参阅以下资源:

文章标题 名称(可选) 电子邮件(可选) 描述

发送建议

注:本教程在Vultr VPS上测试通过,如需部署请前往Vultr.com