Open5

goでs3を操作する

not75743not75743

minioも余裕があればやる
credentialは設定済み

go version go1.22.6 linux/amd64
::::details タイトル
::::
not75743not75743

s3を作る

creates3bucket
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/aws/aws-sdk-go-v2/config"
	"github.com/aws/aws-sdk-go-v2/service/s3"
	"github.com/aws/aws-sdk-go-v2/service/s3/types"
	"github.com/joho/godotenv"
)

func main() {
	// .env ファイルの読み込み
	err := godotenv.Load()
	if err != nil {
		log.Fatalf("Error loading .env file: %v", err)
	}

	// 環境変数からバケット名とリージョンを取得
	bucketName := os.Getenv("BUCKET_NAME")
	region := os.Getenv("REGION")
	if bucketName == "" || region == "" {
		log.Fatalf("BUCKET_NAME or REGION is not set in .env file")
	}

	// AWS設定のロード
	cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion(region))
	if err != nil {
		log.Fatalf("failed to load configuration, %v", err)
	}

	// S3クライアントの作成
	s3Client := s3.NewFromConfig(cfg)

	// バケット作成リクエスト
	createBucketInput := &s3.CreateBucketInput{
		Bucket: &bucketName,
		CreateBucketConfiguration: &types.CreateBucketConfiguration{
			LocationConstraint: types.BucketLocationConstraint(region),
		},
	}

	// バケットの作成
	_, err = s3Client.CreateBucket(context.TODO(), createBucketInput)
	if err != nil {
		log.Fatalf("failed to create bucket, %v", err)
	}

	fmt.Printf("Bucket %s created successfully in region %s\n", bucketName, region)
}
Bucket test-20241130 created successfully in region ap-northeast-1
not75743not75743

s3を削除する

deletes3bucket
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/aws/aws-sdk-go-v2/config"
	"github.com/aws/aws-sdk-go-v2/service/s3"
	"github.com/joho/godotenv"
)

func main() {
	// .env ファイルの読み込み
	err := godotenv.Load()
	if err != nil {
		log.Fatalf("Error loading .env file: %v", err)
	}

	// 環境変数からバケット名とリージョンを取得
	bucketName := os.Getenv("BUCKET_NAME")
	region := os.Getenv("REGION")
	if bucketName == "" || region == "" {
		log.Fatalf("BUCKET_NAME or REGION is not set in .env file")
	}

	// AWS設定のロード
	cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion(region))
	if err != nil {
		log.Fatalf("failed to load configuration, %v", err)
	}

	// S3クライアントの作成
	s3Client := s3.NewFromConfig(cfg)

	// バケット内のオブジェクトを削除
	err = deleteObjectsInBucket(context.TODO(), s3Client, bucketName)
	if err != nil {
		log.Fatalf("failed to delete objects in bucket, %v", err)
	}

	// バケットの削除
	_, err = s3Client.DeleteBucket(context.TODO(), &s3.DeleteBucketInput{
		Bucket: &bucketName,
	})
	if err != nil {
		log.Fatalf("failed to delete bucket, %v", err)
	}

	fmt.Printf("Bucket %s deleted successfully in region %s\n", bucketName, region)
}

// バケット内のすべてのオブジェクトを削除する関数
func deleteObjectsInBucket(ctx context.Context, client *s3.Client, bucketName string) error {
	// バケット内のオブジェクトをリストアップ
	listObjectsOutput, err := client.ListObjectsV2(ctx, &s3.ListObjectsV2Input{
		Bucket: &bucketName,
	})
	if err != nil {
		return fmt.Errorf("failed to list objects in bucket: %v", err)
	}

	// オブジェクトを1つずつ削除
	for _, object := range listObjectsOutput.Contents {
		_, err := client.DeleteObject(ctx, &s3.DeleteObjectInput{
			Bucket: &bucketName,
			Key:    object.Key,
		})
		if err != nil {
			return fmt.Errorf("failed to delete object %s: %v", *object.Key, err)
		}
		fmt.Printf("Deleted object: %s\n", *object.Key)
	}

	return nil
}

Bucket test-20241130 deleted successfully in region ap-northeast-1
not75743not75743

index.htmlをアップロードする

タイトル
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/config"
	"github.com/aws/aws-sdk-go-v2/service/s3"
	"github.com/joho/godotenv"
)

func main() {
	// .env ファイルの読み込み
	err := godotenv.Load()
	if err != nil {
		log.Fatalf("Error loading .env file: %v", err)
	}

	// 環境変数からバケット名とリージョンを取得
	bucketName := os.Getenv("BUCKET_NAME")
	region := os.Getenv("REGION")
	if bucketName == "" || region == "" {
		log.Fatalf("BUCKET_NAME or REGION is not set in .env file")
	}

	// AWS設定のロード
	cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion(region))
	if err != nil {
		log.Fatalf("failed to load configuration, %v", err)
	}

	// S3クライアントの作成
	s3Client := s3.NewFromConfig(cfg)

	// アップロードするファイル名
	fileName := "index.html"

	// ファイルを開く
	file, err := os.Open(fileName)
	if err != nil {
		log.Fatalf("failed to open file %s, %v", fileName, err)
	}
	defer file.Close()

	// ファイル情報を取得
	fileInfo, err := file.Stat()
	if err != nil {
		log.Fatalf("failed to get file info, %v", err)
	}

	// ファイルサイズをポインタ型に変換
	contentLength := fileInfo.Size()

	// アップロードリクエスト
	_, err = s3Client.PutObject(context.TODO(), &s3.PutObjectInput{
		Bucket:        &bucketName,
		Key:           &fileName,
		Body:          file,
		ContentLength: aws.Int64(contentLength),
		ContentType:   aws.String("text/html"),
	})
	if err != nil {
		log.Fatalf("failed to upload file %s to bucket %s, %v", fileName, bucketName, err)
	}

	fmt.Printf("File %s uploaded successfully to bucket %s\n", fileName, bucketName)
}

File index.html uploaded successfully to bucket testbucket-241130
not75743not75743

署名つきURLを払い出す

presignedurl
package main

import (
	"context"
	"fmt"
	"log"
	"os"
	"time"

	"github.com/aws/aws-sdk-go-v2/aws"
	v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4"
	"github.com/aws/aws-sdk-go-v2/config"
	"github.com/aws/aws-sdk-go-v2/service/s3"
	"github.com/joho/godotenv"
)

// Presigner encapsulates the presign actions used for S3
type Presigner struct {
	PresignClient *s3.PresignClient
}

// GetObject generates a presigned URL for downloading an object from S3
func (presigner Presigner) GetObject(ctx context.Context, bucketName string, objectKey string, lifetimeSecs int64) (*v4.PresignedHTTPRequest, error) {
	request, err := presigner.PresignClient.PresignGetObject(ctx, &s3.GetObjectInput{
		Bucket: aws.String(bucketName),
		Key:    aws.String(objectKey),
	}, func(opts *s3.PresignOptions) {
		opts.Expires = time.Duration(lifetimeSecs) * time.Second
	})
	if err != nil {
		log.Printf("Couldn't get a presigned request to get %v:%v. Here's why: %v\n", bucketName, objectKey, err)
		return nil, err
	}
	return request, nil
}

func main() {
	// .env ファイルの読み込み
	err := godotenv.Load()
	if err != nil {
		log.Fatalf("Error loading .env file: %v", err)
	}

	// 環境変数からバケット名とリージョンを取得
	bucketName := os.Getenv("BUCKET_NAME")
	region := os.Getenv("REGION")
	if bucketName == "" || region == "" {
		log.Fatalf("BUCKET_NAME or REGION is not set in .env file")
	}

	// AWS設定のロード
	cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion(region))
	if err != nil {
		log.Fatalf("failed to load configuration, %v", err)
	}

	// S3クライアントの作成
	s3Client := s3.NewFromConfig(cfg)

	// Presignerを初期化
	presigner := Presigner{
		PresignClient: s3.NewPresignClient(s3Client),
	}

	// 署名付きURLを生成するファイル名
	fileName := "index.html"

	// 有効期限を1分(60秒)に設定
	presignedRequest, err := presigner.GetObject(context.TODO(), bucketName, fileName, 60)
	if err != nil {
		log.Fatalf("failed to generate presigned URL, %v", err)
	}

	// 署名付きURLを出力
	fmt.Printf("Presigned URL: %s\n", presignedRequest.URL)
}

Presigned URL: https://testbucket-241130.s3.ap-northeast-1.amazonaws.com/index.html?略