From 219bf718a18af5586dd75838555a74c99c64a368 Mon Sep 17 00:00:00 2001 From: Dejan K Date: Thu, 14 Nov 2024 18:09:31 +0100 Subject: [PATCH] feat: support for custom s3 storage --- pkg/api/signed_url.go | 18 ++++++++++++++++++ pkg/api/signed_url_test.go | 7 +++++++ 2 files changed, 25 insertions(+) diff --git a/pkg/api/signed_url.go b/pkg/api/signed_url.go index bd716f5..04ea4be 100644 --- a/pkg/api/signed_url.go +++ b/pkg/api/signed_url.go @@ -222,6 +222,11 @@ func (u *SignedURL) GetObject() (string, error) { return parseLocalhostURL(URL) default: + if parsed, err := parseCustomS3URL(URL); err == nil { + log.Debugf("Parsing custom S3 URL: %s\n", u.URL) + return parsed, nil + } + log.Warnf("Failed to parse URL '%s' - unrecognized host '%s'\n", u.URL, host) return "", fmt.Errorf("unrecognized host %s", host) } @@ -257,6 +262,19 @@ func parseS3URL(URL *url.URL) (string, error) { return parsed[3], nil } +// S3 Custom URLs can be in format: +// 'https://artifacts.///' +func parseCustomS3URL(URL *url.URL) (string, error) { + re := regexp.MustCompile(`https:\/\/artifacts\.([^/]+)\/[^/]+\/[^/]+\/([^?]+)\?`) + parsed := re.FindStringSubmatch(URL.String()) + if len(parsed) < 3 { + log.Warn("Failed to parse custom S3 URL.\n") + return "", fmt.Errorf("") + } + + return parsed[2], nil +} + // Localhost URLs are used during tests func parseLocalhostURL(URL *url.URL) (string, error) { // we don't want the leading slash diff --git a/pkg/api/signed_url_test.go b/pkg/api/signed_url_test.go index 4fe5604..1171fce 100644 --- a/pkg/api/signed_url_test.go +++ b/pkg/api/signed_url_test.go @@ -63,6 +63,13 @@ func Test__GetObject(t *testing.T) { assert.Equal(t, "artifacts/project/projectid/mydir/myfile.txt", obj) }) + t.Run("Custom S3 - file", func(t *testing.T) { + signedURL := SignedURL{URL: "https://artifacts.test.s3-provider.com/art-bucket/projectid/artifacts/project/projectid/myfile.txt?X-Amz-Whatever"} + obj, err := signedURL.GetObject() + assert.Nil(t, err) + assert.Equal(t, "artifacts/project/projectid/myfile.txt", obj) + }) + t.Run("bad host", func(t *testing.T) { signedURL := SignedURL{URL: "https://somehost.com/projectid/artifacts/project/projectid/myfile.txt"} _, err := signedURL.GetObject()