Support custom Azure publish endpoint

This commit is contained in:
Chuan Liu
2022-04-21 17:04:15 -07:00
committed by Benj Fassbind
parent d955b06f03
commit 152538ccc1
8 changed files with 45 additions and 11 deletions
+1
View File
@@ -45,3 +45,4 @@ List of contributors, in chronological order:
* Lorenzo Bolla (https://github.com/lbolla) * Lorenzo Bolla (https://github.com/lbolla)
* Benj Fassbind (https://github.com/randombenj) * Benj Fassbind (https://github.com/randombenj)
* Markus Muellner (https://github.com/mmianl) * Markus Muellner (https://github.com/mmianl)
* Chuan Liu (https://github.com/chuan)
+31 -3
View File
@@ -5,6 +5,7 @@ import (
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"io" "io"
"net"
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
@@ -29,20 +30,47 @@ var (
_ aptly.PublishedStorage = (*PublishedStorage)(nil) _ aptly.PublishedStorage = (*PublishedStorage)(nil)
) )
func isEmulatorEndpoint(endpoint string) bool {
if h, _, err := net.SplitHostPort(endpoint); err == nil {
endpoint = h
}
if endpoint == "localhost" {
return true
}
// For IPv6, there could be case where SplitHostPort fails for cannot finding port.
// In this case, eliminate the '[' and ']' in the URL.
// For details about IPv6 URL, please refer to https://tools.ietf.org/html/rfc2732
if endpoint[0] == '[' && endpoint[len(endpoint)-1] == ']' {
endpoint = endpoint[1 : len(endpoint)-1]
}
return net.ParseIP(endpoint) != nil
}
// NewPublishedStorage creates published storage from Azure storage credentials // NewPublishedStorage creates published storage from Azure storage credentials
func NewPublishedStorage(accountName, accountKey, container, prefix string) (*PublishedStorage, error) { func NewPublishedStorage(accountName, accountKey, container, prefix, endpoint string) (*PublishedStorage, error) {
credential, err := azblob.NewSharedKeyCredential(accountName, accountKey) credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
if err != nil { if err != nil {
return nil, err return nil, err
} }
containerURL, err := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net/%s", accountName, container)) if endpoint == "" {
endpoint = "blob.core.windows.net"
}
var url *url.URL
if isEmulatorEndpoint(endpoint) {
url, err = url.Parse(fmt.Sprintf("http://%s/%s/%s", endpoint, accountName, container))
} else {
url, err = url.Parse(fmt.Sprintf("https://%s.%s/%s", accountName, endpoint, container))
}
if err != nil { if err != nil {
return nil, err return nil, err
} }
containerURL := azblob.NewContainerURL(*url, azblob.NewPipeline(credential, azblob.PipelineOptions{}))
result := &PublishedStorage{ result := &PublishedStorage{
container: azblob.NewContainerURL(*containerURL, azblob.NewPipeline(credential, azblob.PipelineOptions{})), container: containerURL,
prefix: prefix, prefix: prefix,
} }
+7 -6
View File
@@ -15,8 +15,8 @@ import (
) )
type PublishedStorageSuite struct { type PublishedStorageSuite struct {
accountName, accountKey string accountName, accountKey, endpoint string
storage, prefixedStorage *PublishedStorage storage, prefixedStorage *PublishedStorage
} }
var _ = Suite(&PublishedStorageSuite{}) var _ = Suite(&PublishedStorageSuite{})
@@ -55,6 +55,7 @@ func (s *PublishedStorageSuite) SetUpSuite(c *C) {
println(" 2. AZURE_STORAGE_ACCESS_KEY") println(" 2. AZURE_STORAGE_ACCESS_KEY")
c.Skip("AZURE_STORAGE_ACCESS_KEY not set.") c.Skip("AZURE_STORAGE_ACCESS_KEY not set.")
} }
s.endpoint = os.Getenv("AZURE_STORAGE_ENDPOINT")
} }
func (s *PublishedStorageSuite) SetUpTest(c *C) { func (s *PublishedStorageSuite) SetUpTest(c *C) {
@@ -63,13 +64,13 @@ func (s *PublishedStorageSuite) SetUpTest(c *C) {
var err error var err error
s.storage, err = NewPublishedStorage(s.accountName, s.accountKey, container, "") s.storage, err = NewPublishedStorage(s.accountName, s.accountKey, container, "", s.endpoint)
c.Assert(err, IsNil) c.Assert(err, IsNil)
cnt := s.storage.container cnt := s.storage.container
_, err = cnt.Create(context.Background(), azblob.Metadata{}, azblob.PublicAccessContainer) _, err = cnt.Create(context.Background(), azblob.Metadata{}, azblob.PublicAccessContainer)
c.Assert(err, IsNil) c.Assert(err, IsNil)
s.prefixedStorage, err = NewPublishedStorage(s.accountName, s.accountKey, container, prefix) s.prefixedStorage, err = NewPublishedStorage(s.accountName, s.accountKey, container, prefix, s.endpoint)
c.Assert(err, IsNil) c.Assert(err, IsNil)
} }
@@ -249,7 +250,7 @@ func (s *PublishedStorageSuite) TestRemoveDirsPlus(c *C) {
list, err := s.storage.Filelist("") list, err := s.storage.Filelist("")
c.Check(err, IsNil) c.Check(err, IsNil)
c.Check(list, DeepEquals, []string{"a", "b", "c", "lala/a b", "lala/a+b", "lala/c", "testa"}) c.Check(list, DeepEquals, []string{"a", "b", "c", "lala/a b", "lala/a+b", "lala/c", "testa"})
} }
func (s *PublishedStorageSuite) TestRenameFile(c *C) { func (s *PublishedStorageSuite) TestRenameFile(c *C) {
@@ -354,7 +355,7 @@ func (s *PublishedStorageSuite) TestSymLink(c *C) {
c.Check(err, IsNil) c.Check(err, IsNil)
c.Check(link, Equals, "a/b") c.Check(link, Equals, "a/b")
c.Skip("copy not available in s3test") c.Skip("copy not available in azure test")
} }
func (s *PublishedStorageSuite) TestFileExists(c *C) { func (s *PublishedStorageSuite) TestFileExists(c *C) {
+1 -1
View File
@@ -417,7 +417,7 @@ func (context *AptlyContext) GetPublishedStorage(name string) aptly.PublishedSto
var err error var err error
publishedStorage, err = azure.NewPublishedStorage( publishedStorage, err = azure.NewPublishedStorage(
params.AccountName, params.AccountKey, params.Container, params.Prefix) params.AccountName, params.AccountKey, params.Container, params.Prefix, params.Endpoint)
if err != nil { if err != nil {
Fatal(err) Fatal(err)
} }
+1
View File
@@ -104,6 +104,7 @@ Configuration file is stored in JSON format (default values shown below):
"accountKey": "", "accountKey": "",
"container": "repo", "container": "repo",
"prefix": "" "prefix": ""
"endpoint": "blob.core.windows.net"
} }
} }
} }
+1
View File
@@ -96,6 +96,7 @@ Configuration file is stored in JSON format (default values shown below):
"accountKey": "", "accountKey": "",
"container": "repo", "container": "repo",
"prefix": "" "prefix": ""
"endpoint": "blob.core.windows.net"
} }
} }
} }
+1
View File
@@ -82,6 +82,7 @@ type AzurePublishRoot struct {
AccountKey string `json:"accountKey"` AccountKey string `json:"accountKey"`
Container string `json:"container"` Container string `json:"container"`
Prefix string `json:"prefix"` Prefix string `json:"prefix"`
Endpoint string `json:"endpoint"`
} }
// Config is configuration for aptly, shared by all modules // Config is configuration for aptly, shared by all modules
+2 -1
View File
@@ -124,7 +124,8 @@ func (s *ConfigSuite) TestSaveConfig(c *C) {
" \"accountName\": \"\",\n"+ " \"accountName\": \"\",\n"+
" \"accountKey\": \"\",\n"+ " \"accountKey\": \"\",\n"+
" \"container\": \"repo\",\n"+ " \"container\": \"repo\",\n"+
" \"prefix\": \"\"\n"+ " \"prefix\": \"\",\n"+
" \"endpoint\": \"\"\n"+
" }\n"+ " }\n"+
" },\n"+ " },\n"+
" \"AsyncAPI\": false,\n"+ " \"AsyncAPI\": false,\n"+