github.com/secure-build/gitlab-runner@v12.5.0+incompatible/cache/gcs/adapter.go (about) 1 package gcs 2 3 import ( 4 "fmt" 5 "net/http" 6 "net/url" 7 "time" 8 9 "cloud.google.com/go/storage" 10 "github.com/sirupsen/logrus" 11 12 "gitlab.com/gitlab-org/gitlab-runner/cache" 13 "gitlab.com/gitlab-org/gitlab-runner/common" 14 ) 15 16 type signedURLGenerator func(bucket string, name string, opts *storage.SignedURLOptions) (string, error) 17 18 type gcsAdapter struct { 19 timeout time.Duration 20 config *common.CacheGCSConfig 21 objectName string 22 23 generateSignedURL signedURLGenerator 24 credentialsResolver credentialsResolver 25 } 26 27 func (a *gcsAdapter) GetDownloadURL() *url.URL { 28 return a.presignURL(http.MethodGet, "") 29 } 30 31 func (a *gcsAdapter) GetUploadURL() *url.URL { 32 return a.presignURL(http.MethodPut, "application/octet-stream") 33 } 34 35 func (a *gcsAdapter) presignURL(method string, contentType string) *url.URL { 36 err := a.credentialsResolver.Resolve() 37 if err != nil { 38 logrus.Errorf("error while resolving GCS credentials: %v", err) 39 return nil 40 } 41 42 credentials := a.credentialsResolver.Credentials() 43 44 var privateKey []byte 45 if credentials.PrivateKey != "" { 46 privateKey = []byte(credentials.PrivateKey) 47 } 48 49 if a.config.BucketName == "" { 50 logrus.Error("BucketName can't be empty") 51 return nil 52 } 53 54 rawURL, err := a.generateSignedURL(a.config.BucketName, a.objectName, &storage.SignedURLOptions{ 55 GoogleAccessID: credentials.AccessID, 56 PrivateKey: privateKey, 57 Method: method, 58 Expires: time.Now().Add(a.timeout), 59 ContentType: contentType, 60 }) 61 if err != nil { 62 logrus.Errorf("error while generating GCS pre-signed URL: %v", err) 63 return nil 64 } 65 66 URL, err := url.Parse(rawURL) 67 if err != nil { 68 logrus.Errorf("error while parsing generated URL: %v", err) 69 return nil 70 } 71 72 return URL 73 } 74 75 func New(config *common.CacheConfig, timeout time.Duration, objectName string) (cache.Adapter, error) { 76 gcs := config.GCS 77 if gcs == nil { 78 return nil, fmt.Errorf("missing GCS configuration") 79 } 80 81 cr, err := credentialsResolverInitializer(gcs) 82 if err != nil { 83 return nil, fmt.Errorf("error while initializing GCS credentials resolver: %v", err) 84 } 85 86 a := &gcsAdapter{ 87 config: gcs, 88 timeout: timeout, 89 objectName: objectName, 90 generateSignedURL: storage.SignedURL, 91 credentialsResolver: cr, 92 } 93 94 return a, nil 95 } 96 97 func init() { 98 err := cache.Factories().Register("gcs", New) 99 if err != nil { 100 panic(err) 101 } 102 }