Есть ли способ получить местоположение (publi c url) объекта S3, используя AWS CLI? - PullRequest
1 голос
/ 19 марта 2020

<предпосылка>
Я новичок в области облачных вычислений в целом, AWS, в частности, и REST API, и пытаюсь объединить понимание "общей картины".

Я работаю с LocalStack - который, по моему пониманию, имитирует реальный AWS, идентично реагируя на (подмножество) API AWS, если вы указываете адрес / порт конечной точки, который LocalStack слушает.

Наконец, я работал над этим учебным пособием: https://dev.to/goodidea/how-to-fake-aws-locally-with-localstack-27me

Используя указанное руководство и, согласно его указаниям, я успешно создал S3 корзина с использованием AWS CLI.
Чтобы продемонстрировать загрузку локального файла в S3 корзину, учебник переключается на node.js, что, я думаю, демонстрирует AWS node.js SDK:

# aws.js
# This code segment comes from https://dev.to/goodidea/how-to-fake-aws-locally-with-localstack-27me
#

const AWS = require('aws-sdk')
require('dotenv').config()

const credentials = {
   accessKeyId: process.env.AWS_ACCESS_KEY_ID,
   secretAccessKey: process.env.AWS_SECRET_KEY,
}

const useLocal = process.env.NODE_ENV !== 'production'

const bucketName = process.env.AWS_BUCKET_NAME

const s3client = new AWS.S3({
   credentials,
   /**
    * When working locally, we'll use the Localstack endpoints. This is the one for S3.
    * A full list of endpoints for each service can be found in the Localstack docs.
    */
   endpoint: useLocal ? 'http://localhost:4572' : undefined,
   /**
     * Including this option gets localstack to more closely match the defaults for
     * live S3. If you omit this, you will need to add the bucketName to the `Key`
     * property in the upload function below.
     *
     * see: https://github.com/localstack/localstack/issues/1180
     */
   s3ForcePathStyle: true,
})


const uploadFile = async (data, fileName) =>
   new Promise((resolve) => {
      s3client.upload(
         {
            Bucket: bucketName,
            Key: fileName,
            Body: data,
         },
         (err, response) => {
            if (err) throw err
            resolve(response)
         },
      )
   })

module.exports = uploadFile

.

# test-upload.js
# This code segment comes from https://dev.to/goodidea/how-to-fake-aws-locally-with-localstack-27me
#

const fs = require('fs')
const path = require('path')
const uploadFile = require('./aws')

const testUpload = () => {
   const filePath = path.resolve(__dirname, 'test-image.jpg')
   const fileStream = fs.createReadStream(filePath)
   const now = new Date()
   const fileName = `test-image-${now.toISOString()}.jpg`
   uploadFile(fileStream, fileName).then((response) => {
      console.log(":)")
      console.log(response)
   }).catch((err) => {
      console.log(":|")
      console.log(err)
   })
}

testUpload()

Вызов:

$ node test-upload.js
:)
{ ETag: '"c6b9e5b1863cd01d3962c9385a9281d"',
  Location: 'http://demo-bucket.localhost:4572/demo-bucket/test-image-2019-03-11T21%3A22%3A43.511Z.jpg',
  key: 'demo-bucket/test-image-2019-03-11T21:22:43.511Z.jpg',
  Key: 'demo-bucket/test-image-2019-03-11T21:22:43.511Z.jpg',
  Bucket: 'demo-bucket' }

У меня нет опыта работы с node.js, но мое понимание приведенного выше кода таково, что он использует метод AWS.S3.upload() AWS node.js SDK для копирования локального файла в S3 корзину и печатает ответ HTTP (это правильно?).

Вопрос : я заметил, что ответ HTTP содержит ключ "Location", значение которого похоже на URL, который я могу скопировать / вставить в браузер, чтобы просмотреть изображение прямо из корзины S3; Есть ли способ получить это местоположение с помощью AWS CLI?

Правильно ли я предполагаю, что AWS CLI команды являются аналогами AWS SDK?

Я пытался загрузить файл в мое хранилище S3 с помощью команды CLI aws s3 cp, который, как я думал, будет аналогичен методу AWS.S3.upload(), описанному выше, но он не генерировал никакого вывода, и я не уверен, что я должен был сделать - или нужно сделать - чтобы получить местоположение, как это сделал HTTP-ответ на метод узла SDK AWS.S3.upload() AWS.

$ aws --endpoint-url=http://localhost:4572 s3 cp ./myFile.json s3://myBucket/myFile.json
upload: ./myFile.json to s3://myBucket/myFile.json

Обновление : продолжение обучения заставляет меня теперь Интересно, является ли неявным , что файл загружен в S3 корзину любым способом - будь то с помощью команды CLI aws s3 cp или node.js SDK методом AWS.S3.upload(), et c. - можно получить доступ на http://<bucket_name>.<endpoint_without_http_prefix>/<bucket_name>/<key>? Например, http://myBucket.localhost:4572/myBucket/myFile.json?
Если это неявно , я полагаю, вы могли бы утверждать, что нет необходимости когда-либо указывать "Местоположение", как в этом примере node.js HTTP-ответ.
Благодарен за руководство - Надеюсь, очевидно, насколько болезненно я недостаточно образован по всем задействованным технологиям.


Обновление 2 : похоже, правильный URL-адрес <endpoint>/<bucket_name>/<key>, например http://localhost:4572/myBucket/myFile.json.

1 Ответ

1 голос
/ 20 марта 2020

AWS CLI и различные SDK предлагают схожую функциональность, но некоторые добавляют дополнительные функции, а некоторые по-разному форматируют данные. Можно с уверенностью предположить, что вы можете делать то, что CLI делает с SDK, и наоборот. Возможно, вам иногда придется немного поработать.

Как вы сказали в своем обновлении, не каждый файл, загруженный на S3, является общедоступным. Ведра имеют политики, а файлы имеют разрешения. Файлы доступны только для общественности, если политики и разрешения позволяют это.

Если файл опубликован c, тогда вы можете просто создать URL-адрес, как вы описали. Если у вас есть настройка для хостинга веб-сайтов, вы также можете использовать настроенный домен.

Но если файл не опубликован c или вам нужен только временный URL, вы можете использовать aws presign s3://myBucket/myFile.json. Это даст вам URL, который может быть использован любым пользователем для загрузки файла с разрешениями любого, кто выполнял команду. URL будет действителен в течение одного часа, если вы не выберете другое время с --expires-in. SDK также имеет аналогичную функциональность, но вам придется потрудиться, чтобы использовать его.

...