test: more PutBucketTagging tests, DeleteBucketTagging test

This commit is contained in:
Luke McCrone
2025-10-30 17:01:28 -03:00
parent 8a733b8cbf
commit 1c488422bc
33 changed files with 797 additions and 355 deletions
@@ -0,0 +1,5 @@
package command
type TagAdder interface {
AddTag(tag string, value string) error
}
@@ -0,0 +1,102 @@
package command
import (
"encoding/xml"
"errors"
"fmt"
"strconv"
"strings"
)
type Tag struct {
Key string `xml:"Key"`
Value string `xml:"Value"`
}
type TagSet struct {
Tags []Tag `xml:"Tag"`
}
type PutBucketTaggingTags struct {
XMLName xml.Name `xml:"Tagging"`
XMLNamespace string `xml:"xmlns,attr"`
TagSet TagSet `xml:"TagSet"`
}
type PutBucketTaggingFields struct {
TagCount int
TagKeys []string
TagValues []string
}
type PutBucketTaggingCommand struct {
*S3Command
TagCount *int
Tags *PutBucketTaggingTags
}
func NewPutBucketTaggingCommand(s3Command *S3Command, fields *PutBucketTaggingFields) (*PutBucketTaggingCommand, error) {
if s3Command.BucketName == "" {
return nil, errors.New("PutBucketTagging must have bucket name")
}
s3Command.Method = "PUT"
s3Command.Query = "tagging="
command := &PutBucketTaggingCommand{
S3Command: s3Command,
}
if len(fields.TagKeys) != len(fields.TagValues) {
return nil, errors.New("must be same number of tag keys and tag values")
}
if fields.TagCount > 0 && len(fields.TagKeys) != 0 {
return nil, errors.New("tagCount can not be set simultaneously with tagKeys or tagValues")
}
command.Tags = &PutBucketTaggingTags{
XMLNamespace: "https://s3.amazonaws.com/doc/2006-03-01/",
}
if fields.TagCount > 0 {
command.Tags.GenerateKeyValuePairs(fields.TagCount)
} else if len(fields.TagKeys) != 0 {
if err := command.Tags.AddTags(fields.TagKeys, fields.TagValues); err != nil {
return nil, fmt.Errorf("error adding keys and/or values to payload: %w", err)
}
}
xmlData, err := xml.Marshal(command.Tags)
if err != nil {
return nil, fmt.Errorf("error marshalling XML: %w", err)
}
command.Payload = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + string(xmlData)
command.Payload = strings.Replace(command.Payload, "\"", "\\\"", -1)
return command, nil
}
func (p *PutBucketTaggingTags) GenerateKeyValuePairs(count int) {
p.TagSet.Tags = make([]Tag, 0, count)
for idx := 1; idx <= count; idx++ {
key := fmt.Sprintf("key%d", idx)
value := fmt.Sprintf("value%d", idx)
p.TagSet.Tags = append(p.TagSet.Tags, Tag{
Key: key,
Value: value,
})
}
}
func (p *PutBucketTaggingTags) AddTags(keys, values []string) error {
p.TagSet.Tags = make([]Tag, 0, len(keys))
for idx, key := range keys {
unquotedKey, err := strconv.Unquote(`"` + key + `"`)
if err != nil {
return fmt.Errorf("error unquoting key: %w", err)
}
unquotedValue, err := strconv.Unquote(`"` + values[idx] + `"`)
if err != nil {
return fmt.Errorf("error unquoting key: %w", err)
}
p.TagSet.Tags = append(p.TagSet.Tags, Tag{
Key: unquotedKey,
Value: unquotedValue,
})
}
return nil
}
@@ -0,0 +1,6 @@
package command
type S3CommandConverter interface {
CurlShellCommand() (string, error)
OpenSSLCommand() error
}
+1 -1
View File
@@ -29,7 +29,7 @@ build_canonical_request "${cr_data[@]}"
# shellcheck disable=SC2119
create_canonical_hash_sts_and_signature
curl_command+=(curl -ks -w "\"%{http_code}\"" -X DELETE "https://$host/$bucket_name"
curl_command+=(curl -ks -w "\"%{http_code}\"" -X DELETE "$AWS_ENDPOINT_URL/$bucket_name"
-H "\"Authorization: AWS4-HMAC-SHA256 Credential=$aws_access_key_id/$year_month_day/$aws_region/s3/aws4_request,SignedHeaders=$param_list,Signature=$signature\"")
curl_command+=("${header_fields[@]}")
curl_command+=(-o "$OUTPUT_FILE")
+1 -1
View File
@@ -29,7 +29,7 @@ build_canonical_request "${cr_data[@]}"
# shellcheck disable=SC2119
create_canonical_hash_sts_and_signature
curl_command+=(curl -ks -w "\"%{http_code}\"" -X DELETE "https://$host/$bucket_name?policy"
curl_command+=(curl -ks -w "\"%{http_code}\"" -X DELETE "$AWS_ENDPOINT_URL/$bucket_name?policy"
-H "\"Authorization: AWS4-HMAC-SHA256 Credential=$aws_access_key_id/$year_month_day/$aws_region/s3/aws4_request,SignedHeaders=$param_list,Signature=$signature\"")
curl_command+=("${header_fields[@]}")
curl_command+=(-o "$OUTPUT_FILE")
+40 -4
View File
@@ -14,6 +14,10 @@ const (
OPENSSL = "openssl"
)
const (
PutBucketTagging = "putBucketTagging"
)
var method *string
var url *string
var bucketName *string
@@ -39,6 +43,13 @@ var filePath *string
var client *string
var customHostParam *string
var customHostParamSet bool = false
var commandType *string
type arrayFlags []string
var tagCount *int
var tagKeys arrayFlags
var tagValues arrayFlags
type restParams map[string]string
@@ -51,8 +62,6 @@ func (r *restParams) Set(value string) error {
pairs := strings.Split(value, ",")
for _, pair := range pairs {
kv := strings.SplitN(pair, ":", 2)
if len(kv) != 2 {
}
if len(kv) != 2 {
return fmt.Errorf("invalid key-value pair: %s", pair)
}
@@ -61,12 +70,21 @@ func (r *restParams) Set(value string) error {
return nil
}
func (a *arrayFlags) String() string {
return fmt.Sprintf("%v", *a)
}
func (a *arrayFlags) Set(value string) error {
*a = append(*a, value)
return nil
}
func main() {
if err := checkFlags(); err != nil {
log.Fatalf("Error checking flags: %v", err)
}
s3Command := &command.S3Command{
baseCommand := &command.S3Command{
Method: *method,
Url: *url,
BucketName: *bucketName,
@@ -91,6 +109,21 @@ func main() {
CustomHostParam: *customHostParam,
CustomHostParamSet: customHostParamSet,
}
var s3Command command.S3CommandConverter
var err error
switch *commandType {
case PutBucketTagging:
fields := command.PutBucketTaggingFields{
TagCount: *tagCount,
TagKeys: tagKeys,
TagValues: tagValues,
}
if s3Command, err = command.NewPutBucketTaggingCommand(baseCommand, &fields); err != nil {
log.Fatalf("Error setting up PutBucketTagging command: %v", err)
}
default:
s3Command = baseCommand
}
switch *client {
case CURL:
curlShellCommand, err := s3Command.CurlShellCommand()
@@ -105,7 +138,6 @@ func main() {
default:
log.Fatalln("Invalid client type: ", *client)
}
}
func checkFlags() error {
@@ -133,6 +165,10 @@ func checkFlags() error {
customHostParam = flag.String("customHostParam", "", "Custom host parameter")
filePath = flag.String("filePath", "", "Path to write command (stdout if none)")
client = flag.String("client", CURL, "Command-line client to use")
commandType = flag.String("commandType", "", "Command template to use, if any")
tagCount = flag.Int("tagCount", 0, "Autogenerate this amount of tags for commands with tags")
flag.Var(&tagKeys, "tagKey", "Tag key (can add multiple)")
flag.Var(&tagValues, "tagValue", "Tag value (can add multiple)")
// Parse the flags
flag.Parse()
+1 -1
View File
@@ -39,7 +39,7 @@ UNSIGNED-PAYLOAD"
# shellcheck disable=SC2119
create_canonical_hash_sts_and_signature
curl_command+=(curl -ks -w "\"%{http_code}\"" "https://$host/$bucket_name/$key?uploads="
curl_command+=(curl -ks -w "\"%{http_code}\"" "$AWS_ENDPOINT_URL/$bucket_name/$key?uploads="
-H "\"Authorization: AWS4-HMAC-SHA256 Credential=$aws_access_key_id/$year_month_day/$aws_region/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date,Signature=$signature\""
-H "\"x-amz-content-sha256: UNSIGNED-PAYLOAD\""
-H "\"x-amz-date: $current_date_time\""
+1 -1
View File
@@ -37,7 +37,7 @@ UNSIGNED-PAYLOAD"
# shellcheck disable=SC2119
create_canonical_hash_sts_and_signature
curl_command+=(curl -ks -w "\"%{http_code}\"" "https://$host/$bucket_name?versions"
curl_command+=(curl -ks -w "\"%{http_code}\"" "$AWS_ENDPOINT_URL/$bucket_name?versions"
-H "\"Authorization: AWS4-HMAC-SHA256 Credential=$aws_access_key_id/$year_month_day/$aws_region/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date,Signature=$signature\""
-H "\"x-amz-content-sha256: UNSIGNED-PAYLOAD\""
-H "\"x-amz-date: $current_date_time\""
+1 -1
View File
@@ -41,7 +41,7 @@ UNSIGNED-PAYLOAD"
# shellcheck disable=SC2119
create_canonical_hash_sts_and_signature
curl_command+=(curl -ks -w "\"%{http_code}\"" "https://$host/$bucket_name/$key?uploadId=$upload_id"
curl_command+=(curl -ks -w "\"%{http_code}\"" "$AWS_ENDPOINT_URL/$bucket_name/$key?uploadId=$upload_id"
-H "\"Authorization: AWS4-HMAC-SHA256 Credential=$aws_access_key_id/$year_month_day/$aws_region/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date,Signature=$signature\""
-H "\"x-amz-content-sha256: UNSIGNED-PAYLOAD\""
-H "\"x-amz-date: $current_date_time\""
-1
View File
@@ -1 +0,0 @@
package main