260 lines
9.6 KiB
Go
260 lines
9.6 KiB
Go
package dj
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"github.com/aws/aws-sdk-go/aws"
|
||
awscs "github.com/aws/aws-sdk-go/aws/credentials"
|
||
"github.com/aws/aws-sdk-go/aws/session"
|
||
"github.com/aws/aws-sdk-go/service/sts"
|
||
"github.com/gogf/gf/v2/frame/g"
|
||
"github.com/minio/minio-go/v7"
|
||
"github.com/minio/minio-go/v7/pkg/credentials"
|
||
"log"
|
||
"os"
|
||
"path/filepath"
|
||
"time"
|
||
)
|
||
|
||
//// minio的配置信息
|
||
//const (
|
||
// Endpoint string = coryCommon.Global + ":9999"
|
||
// AccessKeyID string = "admin"
|
||
// SecretAccessKey string = "12345678"
|
||
// BucketName string = "cory-create"
|
||
// RoleARN string = "arn:aws:s3:::cory-create/*"
|
||
// RoleSessionName string = "anysession"
|
||
// Region string = "cn-chengdu"
|
||
// UseSSL bool = true
|
||
// DurationSeconds int64 = 3600
|
||
//
|
||
// // Endpoint string = "jl.yj-3d.com:8154"
|
||
// // AccessKeyID string = "minioadmin"
|
||
// // SecretAccessKey string = "minioadmin"
|
||
// // BucketName string = "cory-create"
|
||
// // RoleARN string = "arn:aws:s3:::cory-create/*"
|
||
// // RoleSessionName string = "anysession"
|
||
// // Region string = "cn-chengdu"
|
||
// // UseSSL bool = true
|
||
// // DurationSeconds int64 = 3600
|
||
//)
|
||
|
||
var (
|
||
Endpoint string
|
||
AccessKeyID string
|
||
SecretAccessKey string
|
||
BucketName string
|
||
RoleARN string
|
||
RoleSessionName string
|
||
Region string
|
||
UseSSL bool
|
||
DurationSeconds int64
|
||
)
|
||
|
||
func init() {
|
||
Endpoint = g.Cfg().MustGet(context.Background(), "minio.endpoint").String()
|
||
AccessKeyID = g.Cfg().MustGet(context.Background(), "minio.accessKeyID").String()
|
||
SecretAccessKey = g.Cfg().MustGet(context.Background(), "minio.secretAccessKey").String()
|
||
BucketName = g.Cfg().MustGet(context.Background(), "minio.bucketName").String()
|
||
RoleSessionName = g.Cfg().MustGet(context.Background(), "minio.roleSessionName").String()
|
||
Region = g.Cfg().MustGet(context.Background(), "minio.region").String()
|
||
UseSSL = g.Cfg().MustGet(context.Background(), "minio.useSSL").Bool()
|
||
DurationSeconds = g.Cfg().MustGet(context.Background(), "minio.durationSeconds").Int64()
|
||
RoleARN = g.Cfg().MustGet(context.Background(), "minio.roleARN").String()
|
||
|
||
}
|
||
|
||
var (
|
||
IsEnablingSSL = false //是否开启SSL安全 (只针对初始化客户端)
|
||
)
|
||
|
||
// PublicMinioClient 初始化MinIO客户端
|
||
func PublicMinioClient() (minioClient *minio.Client, err error) {
|
||
// 获取临时凭证
|
||
token, accessKey, secretAccessKey := MinioVoucher()
|
||
// 初始化MinIO客户端
|
||
minioClient, err = minio.New(Endpoint, &minio.Options{
|
||
Creds: credentials.NewStaticV4(accessKey, secretAccessKey, token),
|
||
Secure: IsEnablingSSL,
|
||
})
|
||
return
|
||
}
|
||
|
||
// MinioVoucher 获取minio的临时凭证
|
||
func MinioVoucher() (sessionToken, accessKey, secretKey string) {
|
||
// 创建AWS会话
|
||
sess, err := session.NewSession(&aws.Config{
|
||
Endpoint: aws.String(Endpoint),
|
||
DisableSSL: aws.Bool(UseSSL),
|
||
Region: aws.String(Region),
|
||
Credentials: awscs.NewStaticCredentials(AccessKeyID, SecretAccessKey, ""),
|
||
})
|
||
if err != nil {
|
||
log.Printf("创建AWS会话错误:%v", err)
|
||
return
|
||
}
|
||
// 创建STS服务客户端
|
||
stsSvc := sts.New(sess)
|
||
|
||
// 获取STS凭证
|
||
input := &sts.AssumeRoleInput{
|
||
RoleArn: aws.String(RoleARN),
|
||
RoleSessionName: aws.String(RoleSessionName),
|
||
DurationSeconds: aws.Int64(DurationSeconds),
|
||
}
|
||
result, err := stsSvc.AssumeRole(input)
|
||
if err != nil {
|
||
fmt.Println("获取STS凭证错误:", err)
|
||
return
|
||
}
|
||
// 获取STS凭证的Token、AccessKey和SecretKey
|
||
sessionToken = *result.Credentials.SessionToken
|
||
accessKey = *result.Credentials.AccessKeyId
|
||
secretKey = *result.Credentials.SecretAccessKey
|
||
return
|
||
}
|
||
|
||
/*
|
||
TheTemporaryAccessUrlIsObtainedBasedOnThePrefixOfTheSpecifiedBucket 根据指定桶的前缀获取到临时访问URL
|
||
bucketName:桶名
|
||
prefix:前缀
|
||
expiry:URL能够访问的时间(最长7天或至少1秒) expiry := 3 * 24 * time.Hour 3天时间访问Url
|
||
isRecursion:是否递归
|
||
*/
|
||
func TheTemporaryAccessUrlIsObtainedBasedOnThePrefixOfTheSpecifiedBucket(ctx context.Context, minioClient *minio.Client, bucketName string, prefix string, expiry time.Duration, isRecursion bool) (url []string) {
|
||
//1、获取递归集
|
||
objectSet := ListAndGenerateURLs(ctx, minioClient, bucketName, prefix, isRecursion)
|
||
//2、根据集获取到临时可访问的URL
|
||
for _, object := range objectSet {
|
||
preSignature := GenerateAnOnlineScopedUrlBasedOnTheObject(ctx, minioClient, bucketName, object.Key, expiry)
|
||
url = append(url, preSignature)
|
||
}
|
||
return
|
||
}
|
||
|
||
/*
|
||
DownloadTheFileWithTheSpecifiedPrefixBasedOnTheObjectSet 根据对象集下载指定前缀的文件
|
||
bucketName:桶名
|
||
prefix:前缀
|
||
filePath:下载后保存路径
|
||
isRecursion:是否递归获取对象集
|
||
*/
|
||
func DownloadTheFileWithTheSpecifiedPrefixBasedOnTheObjectSet(ctx context.Context, minioClient *minio.Client, bucketName string, prefix string, filePath string, isRecursion bool) (err error) {
|
||
objectList := ListAndGenerateURLs(ctx, minioClient, bucketName, prefix, isRecursion)
|
||
for _, object := range objectList {
|
||
//split := strings.Split(object.Key, "/")
|
||
//wz := split[len(split)-1]
|
||
//fileName := strings.Split(wz, ".")[0]
|
||
//if strings.Contains(fileName, "W") {
|
||
// fmt.Println(wz)
|
||
//}
|
||
err = minioClient.FGetObject(ctx, bucketName, object.Key, filepath.ToSlash(filePath+"/"+object.Key), minio.GetObjectOptions{})
|
||
if err != nil {
|
||
fmt.Println("下载minio资源失败:", err)
|
||
return err
|
||
}
|
||
}
|
||
return
|
||
}
|
||
|
||
/*
|
||
DeletesTheFileWithTheSpecifiedPrefixBasedOnTheObjectSet 根据对象集删除指定前缀的文件
|
||
bucketName:桶名
|
||
prefix:前缀
|
||
isRecursion:是否递归获取对象集
|
||
*/
|
||
func DeletesTheFileWithTheSpecifiedPrefixBasedOnTheObjectSet(ctx context.Context, minioClient *minio.Client, bucketName string, prefix string, isRecursion bool) (err error) {
|
||
objectList := ListAndGenerateURLs(ctx, minioClient, bucketName, prefix, isRecursion)
|
||
for _, object := range objectList {
|
||
err = minioClient.RemoveObject(ctx, bucketName, object.Key, minio.RemoveObjectOptions{})
|
||
if err != nil {
|
||
fmt.Println("删除minio资源失败:", err)
|
||
return err
|
||
}
|
||
}
|
||
return
|
||
}
|
||
|
||
/*
|
||
UploadDataAccordingToTemporaryCredentials 根据临时凭证上传数据
|
||
filePath:本地文件路径
|
||
objectName:存储到minio的地址(桶+前缀) 示例:cory-create/uav/key.txt
|
||
*/
|
||
func UploadDataAccordingToTemporaryCredentials(filePath string, objectName string) (err error) {
|
||
minioClient, err := PublicMinioClient()
|
||
if err != nil {
|
||
return
|
||
}
|
||
// 打开文件
|
||
file, err := os.Open(filePath)
|
||
if err != nil {
|
||
fmt.Println("Error opening file:", err)
|
||
return
|
||
}
|
||
defer file.Close()
|
||
// 使用minio-go的PutObject方法上传文件
|
||
n, err := minioClient.PutObject(context.Background(), BucketName, objectName, file, -1, minio.PutObjectOptions{})
|
||
if err != nil {
|
||
fmt.Println("Error uploading file:", err)
|
||
return
|
||
}
|
||
fmt.Printf("Successfully uploaded %s of size %d\n", objectName, n)
|
||
return err
|
||
}
|
||
|
||
//=========================================================================================================================
|
||
//=========================================================================================================================
|
||
//=========================================================================================================================
|
||
//=========================================================================================================================
|
||
//=========================================================================================================================
|
||
//=========================================================================================================================
|
||
//=========================================================================================================================
|
||
//=========================================================================================================================
|
||
|
||
/*
|
||
ListAndGenerateURLs 获取指定前缀下的对象集
|
||
bucketName:桶名
|
||
prefix:前缀(获取哪个下面的对象集) 示例:"uav/9b0af64e1c274105b157a9781961ed99/DJI_202405170903_001_9b0af64e1c274105b157a9781961ed99"
|
||
isRecursion:是否递归
|
||
*/
|
||
func ListAndGenerateURLs(ctx context.Context, minioClient *minio.Client, bucketName string, prefix string, isRecursion bool) (objectInfo []minio.ObjectInfo) {
|
||
// 设置递归为 true,以获取所有对象,包括子目录中的对象
|
||
objectCh := minioClient.ListObjects(ctx, bucketName, minio.ListObjectsOptions{
|
||
Prefix: prefix,
|
||
Recursive: isRecursion,
|
||
})
|
||
// 等待通道中的对象被填充
|
||
for object := range objectCh {
|
||
if object.Err != nil {
|
||
fmt.Println("获取对象列表失败:", object.Err)
|
||
continue
|
||
}
|
||
objectInfo = append(objectInfo, object)
|
||
//fmt.Println("对象名称:", object.Key)
|
||
}
|
||
return
|
||
}
|
||
|
||
// GenerateAnOnlineScopedUrlBasedOnTheObject 根据对象集生成可在线访问的URL
|
||
func GenerateAnOnlineScopedUrlBasedOnTheObject(ctx context.Context, minioClient *minio.Client, bucketName string, objectName string, expiry time.Duration) string {
|
||
// 生成预签名的 GET URL
|
||
presignedURL, err := minioClient.PresignedGetObject(ctx, bucketName, objectName, expiry, nil)
|
||
if err != nil {
|
||
log.Fatalf("生成预签名 URL 失败:%v", err)
|
||
}
|
||
//// 使用预签名 URL 访问对象
|
||
//resp, err := minioClie.
|
||
//nt.GetObject(ctx, bucketName, objectName, minio.GetObjectOptions{})
|
||
//if err != nil {
|
||
// log.Fatalf("获取对象失败:%v", err)
|
||
//}
|
||
//defer resp.Close()
|
||
return presignedURL.String()
|
||
}
|
||
|
||
// StatObjectFunc 获取对象的元数据
|
||
func StatObjectFunc(ctx context.Context, minioClient *minio.Client, bucketName string, objectName string) (objInfo minio.ObjectInfo, err error) {
|
||
objInfo, err = minioClient.StatObject(ctx, bucketName, objectName, minio.GetObjectOptions{})
|
||
return
|
||
}
|