From ff48c35dc8ca65b22d6d5081c1070015077cce89 Mon Sep 17 00:00:00 2001 From: Vladimir Garvardt Date: Thu, 10 Nov 2022 16:17:20 +0100 Subject: [PATCH] Added NewArnFromString to generalize the functionality of ARN parsing (#1721) --- pkg/notification/notification.go | 22 +++++++++++++++++++++ pkg/notification/notification_test.go | 28 +++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/pkg/notification/notification.go b/pkg/notification/notification.go index 97d33a4ec..931ca5bc2 100644 --- a/pkg/notification/notification.go +++ b/pkg/notification/notification.go @@ -21,6 +21,7 @@ import ( "encoding/xml" "errors" "fmt" + "strings" "github.com/minio/minio-go/v7/pkg/set" ) @@ -88,6 +89,27 @@ func NewArn(partition, service, region, accountID, resource string) Arn { } } +var ( + // ErrInvalidArnPrefix is returned when ARN string format does not start with 'arn' + ErrInvalidArnPrefix = errors.New("invalid ARN format, must start with 'arn:'") + // ErrInvalidArnFormat is returned when ARN string format is not valid + ErrInvalidArnFormat = errors.New("invalid ARN format, must be 'arn:::::'") +) + +// NewArnFromString parses string representation of ARN into Arn object. +// Returns an error if the string format is incorrect. +func NewArnFromString(arn string) (Arn, error) { + parts := strings.Split(arn, ":") + if len(parts) != 6 { + return Arn{}, ErrInvalidArnFormat + } + if parts[0] != "arn" { + return Arn{}, ErrInvalidArnPrefix + } + + return NewArn(parts[1], parts[2], parts[3], parts[4], parts[5]), nil +} + // String returns the string format of the ARN func (arn Arn) String() string { return "arn:" + arn.Partition + ":" + arn.Service + ":" + arn.Region + ":" + arn.AccountID + ":" + arn.Resource diff --git a/pkg/notification/notification_test.go b/pkg/notification/notification_test.go index 4cf85ab45..1d6e1782b 100644 --- a/pkg/notification/notification_test.go +++ b/pkg/notification/notification_test.go @@ -1405,3 +1405,31 @@ func TestConfigEqual(t *testing.T) { }) } } + +func TestNewArnFromString(t *testing.T) { + t.Run("valid ARN", func(t *testing.T) { + arn := NewArn("partition", "service", "region", "accountID", "resource") + arnString := arn.String() + arnFromString, err := NewArnFromString(arnString) + if err != nil { + t.Fatalf("did not exect an error, but got %v", err) + } + if arnFromString.String() != arnString { + t.Errorf("expected ARNs to be equal, but they are not: arnFromString = %s, arn = %s", arnFromString.String(), arnString) + } + }) + + t.Run("invalid ARN format", func(t *testing.T) { + _, err := NewArnFromString("arn:only:four:parts") + if err != ErrInvalidArnFormat { + t.Errorf("expected an error %v, but got %v", ErrInvalidArnFormat, err) + } + }) + + t.Run("invalid ARN prefix", func(t *testing.T) { + _, err := NewArnFromString("non-arn:partition:service:region:accountID:resource") + if err != ErrInvalidArnPrefix { + t.Errorf("expected an error %v, but got %v", ErrInvalidArnPrefix, err) + } + }) +}