Add support for GCP Secret Manager
This commit is contained in:
84
google.go
Normal file
84
google.go
Normal file
@@ -0,0 +1,84 @@
|
||||
package secret
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
|
||||
"google.golang.org/api/option"
|
||||
secretmanager "google.golang.org/api/secretmanager/v1"
|
||||
)
|
||||
|
||||
type gcpSecretManagerProvider struct {
|
||||
options *providerOptions
|
||||
projectID string
|
||||
}
|
||||
|
||||
// GCPSecretManager is a provider for Google Cloud Secret Manager.
|
||||
//
|
||||
// Authentication must be supplied using `opts`.
|
||||
//
|
||||
// To use an API key:
|
||||
//
|
||||
// provider, err := GCPSecretManager(projectID, WithAPIKey("AI..."))
|
||||
//
|
||||
// To use credentials JSON:
|
||||
//
|
||||
// provider, err := GCPSecretManager(projectID, WithCredentials("path/to/creds.json"))
|
||||
//
|
||||
// Alternatively, the following environment variables may be used:
|
||||
// - GOOGLE_CLOUD_CREDENTIALS containing a path to the credentials JSON file
|
||||
// - GOOGLE_CLOUD_CREDENTIALS_JSON containing the credentials JSON
|
||||
func GCPSecretManager(projectID string, opts ...Option) (Provider, error) {
|
||||
var options = new(providerOptions)
|
||||
for _, opt := range opts {
|
||||
opt(options)
|
||||
}
|
||||
|
||||
return &gcpSecretManagerProvider{
|
||||
options: options,
|
||||
projectID: projectID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *gcpSecretManagerProvider) GetSecret(key string) (value []byte, err error) {
|
||||
ctx := context.Background()
|
||||
|
||||
if p.options.timeout > 0 {
|
||||
var cancel func()
|
||||
ctx, cancel = context.WithTimeout(ctx, p.options.timeout)
|
||||
defer cancel()
|
||||
}
|
||||
|
||||
var opts []option.ClientOption
|
||||
if p.options.apiKey != "" {
|
||||
opts = append(opts, option.WithAPIKey(p.options.apiKey))
|
||||
} else if p.options.credentials != "" {
|
||||
opts = append(opts, option.WithCredentialsFile(p.options.credentials))
|
||||
} else if v := os.Getenv("GOOGLE_CLOUD_CREDENTIALS"); v != "" {
|
||||
opts = append(opts, option.WithCredentialsFile(v))
|
||||
} else if v := os.Getenv("GOOGLE_CLOUD_CREDENTIALS_JSON"); v != "" {
|
||||
opts = append(opts, option.WithCredentialsJSON([]byte(v)))
|
||||
} else {
|
||||
// Calling the service without authentication will fail...
|
||||
opts = append(opts, option.WithoutAuthentication())
|
||||
}
|
||||
|
||||
var service *secretmanager.Service
|
||||
if service, err = secretmanager.NewService(ctx, opts...); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
resource := fmt.Sprintf("projects/%s/secrets/%s/versions/latest",
|
||||
url.PathEscape(p.projectID),
|
||||
url.PathEscape(key))
|
||||
|
||||
var response *secretmanager.AccessSecretVersionResponse
|
||||
if response, err = service.Projects.Secrets.Versions.Access(resource).Do(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return base64.StdEncoding.DecodeString(response.Payload.Data)
|
||||
}
|
Reference in New Issue
Block a user