mirror of
https://github.com/minio/minio.git
synced 2025-01-24 13:13:16 -05:00
s3-check-md5: Add --modified-since flag to skip some objects (#17410)
This commit is contained in:
parent
ad4e511026
commit
8c33fdf5f4
@ -26,8 +26,10 @@ import (
|
||||
"log"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/minio/minio-go/v7"
|
||||
"github.com/minio/minio-go/v7/pkg/credentials"
|
||||
@ -35,6 +37,7 @@ import (
|
||||
|
||||
var (
|
||||
endpoint, accessKey, secretKey string
|
||||
minModTimeStr string
|
||||
bucket, prefix string
|
||||
debug bool
|
||||
versions bool
|
||||
@ -57,6 +60,7 @@ func main() {
|
||||
flag.BoolVar(&debug, "debug", false, "Prints HTTP network calls to S3 endpoint")
|
||||
flag.BoolVar(&versions, "versions", false, "Verify all versions")
|
||||
flag.BoolVar(&insecure, "insecure", false, "Disable TLS verification")
|
||||
flag.StringVar(&minModTimeStr, "modified-since", "", "Specify a minimum object last modified time, e.g.: 2023-01-02T15:04:05Z")
|
||||
flag.Parse()
|
||||
|
||||
if endpoint == "" {
|
||||
@ -75,6 +79,15 @@ func main() {
|
||||
log.Fatalln("--prefix is specified without --bucket.")
|
||||
}
|
||||
|
||||
var minModTime time.Time
|
||||
if minModTimeStr != "" {
|
||||
var e error
|
||||
minModTime, e = time.Parse(time.RFC3339, minModTimeStr)
|
||||
if e != nil {
|
||||
log.Fatalln("Unable to parse --modified-since:", e)
|
||||
}
|
||||
}
|
||||
|
||||
u, err := url.Parse(endpoint)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
@ -124,22 +137,33 @@ func main() {
|
||||
WithMetadata: true,
|
||||
}
|
||||
|
||||
objFullPath := func(obj minio.ObjectInfo) (fpath string) {
|
||||
fpath = path.Join(bucket, obj.Key)
|
||||
if versions {
|
||||
fpath += ":" + obj.VersionID
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// List all objects from a bucket-name with a matching prefix.
|
||||
for object := range s3Client.ListObjects(context.Background(), bucket, opts) {
|
||||
if object.Err != nil {
|
||||
log.Println("LIST error:", object.Err)
|
||||
log.Println("FAILED: LIST with error:", object.Err)
|
||||
continue
|
||||
}
|
||||
if !minModTime.IsZero() && object.LastModified.Before(minModTime) {
|
||||
continue
|
||||
}
|
||||
if object.IsDeleteMarker {
|
||||
log.Println("DELETE marker skipping object:", object.Key)
|
||||
log.Println("SKIPPED: DELETE marker object:", objFullPath(object))
|
||||
continue
|
||||
}
|
||||
if _, ok := object.UserMetadata["X-Amz-Server-Side-Encryption-Customer-Algorithm"]; ok {
|
||||
log.Println("Objects encrypted with SSE-C do not have md5sum as ETag:", object.Key)
|
||||
log.Println("SKIPPED: Objects encrypted with SSE-C do not have md5sum as ETag:", objFullPath(object))
|
||||
continue
|
||||
}
|
||||
if v, ok := object.UserMetadata["X-Amz-Server-Side-Encryption"]; ok && v == "aws:kms" {
|
||||
log.Println("Objects encrypted with SSE-KMS do not have md5sum as ETag:", object.Key)
|
||||
log.Println("FAILED: encrypted with SSE-KMS do not have md5sum as ETag:", objFullPath(object))
|
||||
continue
|
||||
}
|
||||
parts := 1
|
||||
@ -152,12 +176,12 @@ func main() {
|
||||
if p, err := strconv.Atoi(s[1]); err == nil {
|
||||
parts = p
|
||||
} else {
|
||||
log.Println("ETAG: wrong format:", err)
|
||||
log.Println("FAILED: ETAG of", objFullPath(object), "has a wrong format:", err)
|
||||
continue
|
||||
}
|
||||
multipart = true
|
||||
default:
|
||||
log.Println("Unexpected ETAG format", object.ETag)
|
||||
log.Println("FAILED: Unexpected ETAG", object.ETag, "for object:", objFullPath(object))
|
||||
continue
|
||||
}
|
||||
|
||||
@ -170,13 +194,13 @@ func main() {
|
||||
}
|
||||
obj, err := s3Client.GetObject(context.Background(), bucket, object.Key, opts)
|
||||
if err != nil {
|
||||
log.Println("GET", bucket, object.Key, object.VersionID, "=>", err)
|
||||
log.Println("FAILED: GET", objFullPath(object), "=>", err)
|
||||
failedMD5 = true
|
||||
break
|
||||
}
|
||||
h := md5.New()
|
||||
if _, err := io.Copy(h, obj); err != nil {
|
||||
log.Println("MD5 calculation error:", bucket, object.Key, object.VersionID, "=>", err)
|
||||
log.Println("FAILED: MD5 calculation error:", objFullPath(object), "=>", err)
|
||||
failedMD5 = true
|
||||
break
|
||||
}
|
||||
@ -184,7 +208,7 @@ func main() {
|
||||
}
|
||||
|
||||
if failedMD5 {
|
||||
log.Println("CORRUPTED object:", bucket, object.Key, object.VersionID)
|
||||
log.Println("CORRUPTED object:", objFullPath(object))
|
||||
continue
|
||||
}
|
||||
|
||||
@ -206,9 +230,9 @@ func main() {
|
||||
}
|
||||
|
||||
if corrupted {
|
||||
log.Println("CORRUPTED object:", bucket, object.Key, object.VersionID)
|
||||
log.Println("CORRUPTED object:", objFullPath(object))
|
||||
} else {
|
||||
log.Println("INTACT object:", bucket, object.Key, object.VersionID)
|
||||
log.Println("INTACT object:", objFullPath(object))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user