Files
zmkgC/third/plane/dj/minio.go

260 lines
9.6 KiB
Go
Raw Normal View History

2025-07-07 20:11:59 +08:00
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前缀
expiryURL能够访问的时间最长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
}