mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-07-16 12:08:04 +00:00
Support custom Azure publish endpoint
This commit is contained in:
@@ -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
@@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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"+
|
||||||
|
|||||||
Reference in New Issue
Block a user