mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-01-12 03:21:33 +00:00
Support custom Azure publish endpoint
This commit is contained in:
1
AUTHORS
1
AUTHORS
@@ -45,3 +45,4 @@ List of contributors, in chronological order:
|
||||
* Lorenzo Bolla (https://github.com/lbolla)
|
||||
* Benj Fassbind (https://github.com/randombenj)
|
||||
* Markus Muellner (https://github.com/mmianl)
|
||||
* Chuan Liu (https://github.com/chuan)
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
@@ -29,20 +30,47 @@ var (
|
||||
_ 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
|
||||
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)
|
||||
if err != nil {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
containerURL := azblob.NewContainerURL(*url, azblob.NewPipeline(credential, azblob.PipelineOptions{}))
|
||||
|
||||
result := &PublishedStorage{
|
||||
container: azblob.NewContainerURL(*containerURL, azblob.NewPipeline(credential, azblob.PipelineOptions{})),
|
||||
container: containerURL,
|
||||
prefix: prefix,
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ import (
|
||||
)
|
||||
|
||||
type PublishedStorageSuite struct {
|
||||
accountName, accountKey string
|
||||
storage, prefixedStorage *PublishedStorage
|
||||
accountName, accountKey, endpoint string
|
||||
storage, prefixedStorage *PublishedStorage
|
||||
}
|
||||
|
||||
var _ = Suite(&PublishedStorageSuite{})
|
||||
@@ -55,6 +55,7 @@ func (s *PublishedStorageSuite) SetUpSuite(c *C) {
|
||||
println(" 2. AZURE_STORAGE_ACCESS_KEY")
|
||||
c.Skip("AZURE_STORAGE_ACCESS_KEY not set.")
|
||||
}
|
||||
s.endpoint = os.Getenv("AZURE_STORAGE_ENDPOINT")
|
||||
}
|
||||
|
||||
func (s *PublishedStorageSuite) SetUpTest(c *C) {
|
||||
@@ -63,13 +64,13 @@ func (s *PublishedStorageSuite) SetUpTest(c *C) {
|
||||
|
||||
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)
|
||||
cnt := s.storage.container
|
||||
_, err = cnt.Create(context.Background(), azblob.Metadata{}, azblob.PublicAccessContainer)
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -249,7 +250,7 @@ func (s *PublishedStorageSuite) TestRemoveDirsPlus(c *C) {
|
||||
|
||||
list, err := s.storage.Filelist("")
|
||||
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) {
|
||||
@@ -354,7 +355,7 @@ func (s *PublishedStorageSuite) TestSymLink(c *C) {
|
||||
c.Check(err, IsNil)
|
||||
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) {
|
||||
|
||||
@@ -417,7 +417,7 @@ func (context *AptlyContext) GetPublishedStorage(name string) aptly.PublishedSto
|
||||
|
||||
var err error
|
||||
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 {
|
||||
Fatal(err)
|
||||
}
|
||||
|
||||
@@ -104,6 +104,7 @@ Configuration file is stored in JSON format (default values shown below):
|
||||
"accountKey": "",
|
||||
"container": "repo",
|
||||
"prefix": ""
|
||||
"endpoint": "blob.core.windows.net"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,6 +96,7 @@ Configuration file is stored in JSON format (default values shown below):
|
||||
"accountKey": "",
|
||||
"container": "repo",
|
||||
"prefix": ""
|
||||
"endpoint": "blob.core.windows.net"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ type AzurePublishRoot struct {
|
||||
AccountKey string `json:"accountKey"`
|
||||
Container string `json:"container"`
|
||||
Prefix string `json:"prefix"`
|
||||
Endpoint string `json:"endpoint"`
|
||||
}
|
||||
|
||||
// Config is configuration for aptly, shared by all modules
|
||||
|
||||
@@ -124,7 +124,8 @@ func (s *ConfigSuite) TestSaveConfig(c *C) {
|
||||
" \"accountName\": \"\",\n"+
|
||||
" \"accountKey\": \"\",\n"+
|
||||
" \"container\": \"repo\",\n"+
|
||||
" \"prefix\": \"\"\n"+
|
||||
" \"prefix\": \"\",\n"+
|
||||
" \"endpoint\": \"\"\n"+
|
||||
" }\n"+
|
||||
" },\n"+
|
||||
" \"AsyncAPI\": false,\n"+
|
||||
|
||||
Reference in New Issue
Block a user