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
|
|||
|
}
|