Skip to content

Commit e53a258

Browse files
adam6878yaron2
andauthored
Feature/s3 add tagging to metadata (#3799)
Signed-off-by: adam6878 <[email protected]> Co-authored-by: Yaron Schneider <[email protected]>
1 parent 4dfc9e5 commit e53a258

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

bindings/aws/s3/s3.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ const (
4949
metadataFilePath = "filePath"
5050
metadataPresignTTL = "presignTTL"
5151
metadataStorageClass = "storageClass"
52+
metadataTags = "tags"
5253

5354
metatadataContentType = "Content-Type"
5455
metadataKey = "key"
@@ -191,6 +192,15 @@ func (s *AWSS3) create(ctx context.Context, req *bindings.InvokeRequest) (*bindi
191192
if contentTypeStr != "" {
192193
contentType = &contentTypeStr
193194
}
195+
196+
var tagging *string
197+
if rawTags, ok := req.Metadata[metadataTags]; ok {
198+
tagging, err = s.parseS3Tags(rawTags)
199+
if err != nil {
200+
return nil, fmt.Errorf("s3 binding error: parsing tags falied error: %w", err)
201+
}
202+
}
203+
194204
var r io.Reader
195205
if metadata.FilePath != "" {
196206
r, err = os.Open(metadata.FilePath)
@@ -209,12 +219,14 @@ func (s *AWSS3) create(ctx context.Context, req *bindings.InvokeRequest) (*bindi
209219
if metadata.StorageClass != "" {
210220
storageClass = aws.String(metadata.StorageClass)
211221
}
222+
212223
resultUpload, err := s.authProvider.S3().Uploader.UploadWithContext(ctx, &s3manager.UploadInput{
213224
Bucket: ptr.Of(metadata.Bucket),
214225
Key: ptr.Of(key),
215226
Body: r,
216227
ContentType: contentType,
217228
StorageClass: storageClass,
229+
Tagging: tagging,
218230
})
219231
if err != nil {
220232
return nil, fmt.Errorf("s3 binding error: uploading failed: %w", err)
@@ -418,6 +430,26 @@ func (s *AWSS3) parseMetadata(md bindings.Metadata) (*s3Metadata, error) {
418430
return &m, nil
419431
}
420432

433+
// Helper for parsing s3 tags metadata
434+
func (s *AWSS3) parseS3Tags(raw string) (*string, error) {
435+
tagEntries := strings.Split(raw, ",")
436+
pairs := make([]string, 0, len(tagEntries))
437+
for _, tagEntry := range tagEntries {
438+
kv := strings.SplitN(strings.TrimSpace(tagEntry), "=", 2)
439+
isInvalidTag := len(kv) != 2 || strings.TrimSpace(kv[0]) == "" || strings.TrimSpace(kv[1]) == ""
440+
if isInvalidTag {
441+
return nil, fmt.Errorf("invalid tag format: '%s' (expected key=value)", tagEntry)
442+
}
443+
pairs = append(pairs, fmt.Sprintf("%s=%s", strings.TrimSpace(kv[0]), strings.TrimSpace(kv[1])))
444+
}
445+
446+
if len(pairs) == 0 {
447+
return nil, nil
448+
}
449+
450+
return aws.String(strings.Join(pairs, "&")), nil
451+
}
452+
421453
// Helper to merge config and request metadata.
422454
func (metadata s3Metadata) mergeWithRequestMetadata(req *bindings.InvokeRequest) (s3Metadata, error) {
423455
merged := metadata

bindings/aws/s3/s3_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,24 @@ func TestParseMetadata(t *testing.T) {
5353
})
5454
}
5555

56+
func TestParseS3Tags(t *testing.T) {
57+
t.Run("Has parsed s3 tags", func(t *testing.T) {
58+
request := bindings.InvokeRequest{}
59+
request.Metadata = map[string]string{
60+
"decodeBase64": "yes",
61+
"encodeBase64": "false",
62+
"filePath": "/usr/vader.darth",
63+
"storageClass": "STANDARD_IA",
64+
"tags": "project=myproject,year=2024",
65+
}
66+
s3 := AWSS3{}
67+
parsedTags, err := s3.parseS3Tags(request.Metadata["tags"])
68+
69+
require.NoError(t, err)
70+
assert.Equal(t, "project=myproject&year=2024", *parsedTags)
71+
})
72+
}
73+
5674
func TestMergeWithRequestMetadata(t *testing.T) {
5775
t.Run("Has merged metadata", func(t *testing.T) {
5876
m := bindings.Metadata{}

0 commit comments

Comments
 (0)