Skip to content

Commit 8ebe80f

Browse files
authored
Merge pull request #1550 from linuxdataflow/feat/pls/gcs-support
Add support for GCS.
2 parents 9bb8de6 + b0c6511 commit 8ebe80f

22 files changed

Lines changed: 1786 additions & 54 deletions

.golangci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
version: "2"
2+
run:
3+
timeout: 5m
24
linters:
35
settings:
46
staticcheck:

api/api_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"net/http"
99
"net/http/httptest"
1010
"os"
11+
"sort"
1112
"strings"
1213
"testing"
1314

@@ -41,6 +42,17 @@ func createTestConfig() *os.File {
4142
jsonString, err := json.Marshal(gin.H{
4243
"architectures": []string{},
4344
"enableMetricsEndpoint": true,
45+
"S3PublishEndpoints": map[string]map[string]string{
46+
"test-s3": {
47+
"region": "us-east-1",
48+
"bucket": "bucket-s3",
49+
},
50+
},
51+
"GcsPublishEndpoints": map[string]map[string]string{
52+
"test-gcs": {
53+
"bucket": "bucket-gcs",
54+
},
55+
},
4456
})
4557
if err != nil {
4658
return nil
@@ -173,3 +185,27 @@ func (s *APISuite) TestTruthy(c *C) {
173185
c.Check(truthy(-1), Equals, true)
174186
c.Check(truthy(gin.H{}), Equals, true)
175187
}
188+
189+
func (s *APISuite) TestGetS3Endpoints(c *C) {
190+
response, err := s.HTTPRequest("GET", "/api/s3", nil)
191+
c.Assert(err, IsNil)
192+
c.Check(response.Code, Equals, 200)
193+
194+
var endpoints []string
195+
err = json.Unmarshal(response.Body.Bytes(), &endpoints)
196+
c.Assert(err, IsNil)
197+
sort.Strings(endpoints)
198+
c.Check(endpoints, DeepEquals, []string{"test-s3"})
199+
}
200+
201+
func (s *APISuite) TestGetGCSEndpoints(c *C) {
202+
response, err := s.HTTPRequest("GET", "/api/gcs", nil)
203+
c.Assert(err, IsNil)
204+
c.Check(response.Code, Equals, 200)
205+
206+
var endpoints []string
207+
err = json.Unmarshal(response.Body.Bytes(), &endpoints)
208+
c.Assert(err, IsNil)
209+
sort.Strings(endpoints)
210+
c.Check(endpoints, DeepEquals, []string{"test-gcs"})
211+
}

api/gcs.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package api
2+
3+
import (
4+
"github.com/gin-gonic/gin"
5+
)
6+
7+
// @Summary GCS buckets
8+
// @Description **Get list of GCS buckets**
9+
// @Description
10+
// @Description List configured GCS buckets.
11+
// @Tags Status
12+
// @Produce json
13+
// @Success 200 {array} string "List of GCS buckets"
14+
// @Router /api/gcs [get]
15+
func apiGCSList(c *gin.Context) {
16+
keys := []string{}
17+
for k := range context.Config().GCSPublishRoots {
18+
keys = append(keys, k)
19+
}
20+
c.JSON(200, keys)
21+
}

api/router.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ func Router(c *ctx.AptlyContext) http.Handler {
177177

178178
{
179179
api.GET("/s3", apiS3List)
180+
api.GET("/gcs", apiGCSList)
180181
}
181182

182183
{

context/context.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/aptly-dev/aptly/database/goleveldb"
2424
"github.com/aptly-dev/aptly/deb"
2525
"github.com/aptly-dev/aptly/files"
26+
"github.com/aptly-dev/aptly/gcs"
2627
"github.com/aptly-dev/aptly/http"
2728
"github.com/aptly-dev/aptly/pgp"
2829
"github.com/aptly-dev/aptly/s3"
@@ -437,6 +438,20 @@ func (context *AptlyContext) GetPublishedStorage(name string) aptly.PublishedSto
437438
if err != nil {
438439
Fatal(err)
439440
}
441+
} else if strings.HasPrefix(name, "gcs:") {
442+
params, ok := context.config().GCSPublishRoots[name[4:]]
443+
if !ok {
444+
Fatal(fmt.Errorf("published GCS storage %v not configured", name[4:]))
445+
}
446+
447+
var err error
448+
publishedStorage, err = gcs.NewPublishedStorage(
449+
params.Bucket, params.Prefix, params.CredentialsFile, params.ServiceAccountJSON,
450+
params.Project, params.Endpoint, params.ACL, params.StorageClass, params.EncryptionKey,
451+
params.DisableMultiDel, params.Debug)
452+
if err != nil {
453+
Fatal(err)
454+
}
440455
} else if strings.HasPrefix(name, "swift:") {
441456
params, ok := context.config().SwiftPublishRoots[name[6:]]
442457
if !ok {

debian/aptly.conf

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,58 @@ s3_publish_endpoints:
256256
# # Enables detailed request/response dump for each S3 operation
257257
# debug: false
258258

259+
# GCS Endpoint Support
260+
#
261+
# aptly can be configured to publish repositories directly to Google Cloud
262+
# Storage. First, publishing endpoints should be described in the aptly
263+
# configuration file. Each endpoint has a name and associated settings.
264+
#
265+
# In order to publish to GCS, specify endpoint as `gcs:endpoint-name:` before
266+
# publishing prefix on the command line, e.g.:
267+
#
268+
# `aptly publish snapshot wheezy-main gcs:test:`
269+
#
270+
gcs_publish_endpoints:
271+
# # Endpoint Name
272+
# test:
273+
# # Bucket name
274+
# bucket: test-bucket
275+
# # Prefix (optional)
276+
# # publishing under specified prefix in the bucket, defaults to
277+
# # no prefix (bucket root)
278+
# prefix: ""
279+
# # Credentials File (optional)
280+
# # Path to a service account credentials JSON file
281+
# credentials_file: ""
282+
# # Service Account JSON (optional)
283+
# # Inline service account credentials JSON payload
284+
# service_account_json: ""
285+
# # Project (optional)
286+
# # Quota project used for GCS requests
287+
# project: ""
288+
# # Endpoint (optional)
289+
# # Override the GCS endpoint (e.g. for staging or a fake server);
290+
# # leave empty to use the default GCS endpoint
291+
# endpoint: ""
292+
# # Default ACLs (optional)
293+
# # assign ACL to published files:
294+
# # * private (default)
295+
# # * public-read (public repository)
296+
# # * none (don't set ACL)
297+
# acl: private
298+
# # Storage Class (optional)
299+
# # GCS storage class, e.g. `STANDARD`
300+
# storage_class: STANDARD
301+
# # Encryption Key (optional)
302+
# # Customer-supplied encryption key (32-byte AES-256 key)
303+
# encryption_key: ""
304+
# # Disable MultiDel (optional)
305+
# # Kept for parity with S3 settings; GCS deletes are one-by-one
306+
# disable_multidel: false
307+
# # Debug (optional)
308+
# # Enables detailed logs for each GCS operation
309+
# debug: false
310+
259311
# Swift Endpoint Support
260312
#
261313
# aptly can publish a repository directly to OpenStack Swift.

gcs/gcs.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// Package gcs handles publishing to Google Cloud Storage.
2+
package gcs

gcs/gcs_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package gcs
2+
3+
import (
4+
"testing"
5+
6+
. "gopkg.in/check.v1"
7+
)
8+
9+
// Launch gocheck tests.
10+
func Test(t *testing.T) {
11+
TestingT(t)
12+
}

0 commit comments

Comments
 (0)