Categories: Golang

Как подключиться к Yandex Cloud Storage через AWS S3 golang

Проблема

Если вы вдруг решили подключиться в Yandex Cloud Storage с помощью библиотеки golang aws, у вас могут возникнуть проблемы. Давайте попробуем разобраться.

Официальная документация

В документации от яндекса, есть пример, как мы можем подключиться к их хранилищу с помощью golang aws библиотеки.

Если вы пришли сюда, то скорее всего изучили уже ее и у вас ничего не получилось, но на всякий случай, вот ссылка на ее.

Вы можете столкнуться с двумя проблемами.

Проблема с «unknown endpoint requested»

У вас может возникнуть это ошибка, если вы указали регион как в документации, «ru-central1», попробуйте указать регион «us-east-1», то есть выглядеть это будет так:

customResolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
  if service == s3.ServiceID && region == "us-east-1" {
   return aws.Endpoint{
    PartitionID:   "yc",
    URL:           "https://storage.yandexcloud.net",
    SigningRegion: "ru-central1",
   }, nil
  }
  return aws.Endpoint{}, fmt.Errorf("unknown endpoint requested")
 })

То есть в if блоке заменим регион на другой.

Проблема SignatureDoesNotMatch

После этого, вы скорее всего получите ошибку StatusCode: 403, RequestID: 42e13ec9e5a8e84f, HostID: , api error SignatureDoesNotMatch: The request signature we calculated does not match the signature you provided. Check your key and signing method.

Дело в том, что яндекс документация предлагает вам хранить ключи в .aws папке, но мы не хотим их там хранить, а хотим прописать где-нибудь в конфиге, или использовать какой-нибудь другой метод.

Решение

Например, я сделал себе access и secret key, и хочу подключаться по ним. Поэтому мне надо добавить в LoadDefaultConfig метод, кроме WithEndpointResolverWithOptions, еще и WithCredentialsProvider, получается примерно так.

cfg, err := config.LoadDefaultConfig(
  context.TODO(),
  config.WithEndpointResolverWithOptions(customResolver),
  config.WithCredentialsProvider(
   &credentials.StaticCredentialsProvider{
    Value: aws.Credentials{
     AccessKeyID:     "AccessKeyID",
     SecretAccessKey: "SecretAccessKey",
    }}))

Вместо «AccessKeyID» и «SecretAccessKey» вам надо указать свой ключ и секрет, соответственно.

После этого у вас должен заработать ваш код

Итог

Итоговый код подключения у вас должен выглядеть так

func main() {
 customResolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
  if service == s3.ServiceID && region == "us-east-1" {
   return aws.Endpoint{
    PartitionID:   "yc",
    URL:           "https://storage.yandexcloud.net",
    SigningRegion: "us-east-1",
   }, nil
  }
  return aws.Endpoint{}, fmt.Errorf("unknown endpoint requested")
 })

 cfg, err := config.LoadDefaultConfig(
  ctx,
  config.WithEndpointResolverWithOptions(customResolver),
  config.WithCredentialsProvider(
   &credentials.StaticCredentialsProvider{
    Value: aws.Credentials{
     AccessKeyID:     "AccessKeyID",
     SecretAccessKey: "SecretAccessKey",
    }}))
 client := s3.NewFromConfig(cfg)
 result, err := client.ListBuckets(context.TODO(), &s3.ListBucketsInput{})
 if err != nil {
  log.Fatal(err)
 }
 for _, bucket := range result.Buckets {
  log.Printf("bucket=%s creation time=%s", aws.ToString(bucket.Name), bucket.CreationDate.Format("2006-01-02 15:04:05 Monday"))
 }
}

Так же, вы можете указать другой провайдер.

Denis Pershin

Published by
Denis Pershin

Recent Posts

Как исправить ошибку «Write Failed: broken pipe» при SSH соединении

Ошибка "Write Failed: broken pipe" в SSH соединении обычно возникает, когда клиент или сервер разрывает…

11 месяцев ago

Java Enum — перечисления в Java

Что такое Enum в Java Перечисление (enum) в Java - это тип данных, который позволяет…

2 года ago

Массивы в Java — создание, доступ к элементам, изменение данных

Что такое массивы? Массив - это структура данных в Java, которая представляет собой упорядоченную коллекцию…

2 года ago

ArrayList в Java — Основное

ArrayList в Java - это класс, предоставляющий возможность создания массива переменной длины, который можно изменять…

2 года ago

JDK MIssion Control на Mac

В данной заметке я попытаюсь рассказать как исправить ошибку с запуском JDK Mission Control на…

2 года ago

Отказываемся от Docker Desktop на Mac OS

Привет! В свете последних событий приходится отказываться от Docker Desktop, но без его использования, мы…

2 года ago

This website uses cookies.