-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Mads Schou-Andreasen
committed
Jan 3, 2021
1 parent
c343a61
commit c12c859
Showing
3 changed files
with
154 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package gcpsecretfetch | ||
|
||
import ( | ||
secretmanager "cloud.google.com/go/secretmanager/apiv1" | ||
"context" | ||
"github.com/pkg/errors" | ||
) | ||
|
||
type secretClient struct { | ||
client *secretmanager.Client | ||
project string | ||
ctx context.Context | ||
} | ||
|
||
func newClient(project string) (*secretClient, error) { | ||
ctx := context.Background() | ||
client, err := secretmanager.NewClient(ctx) | ||
if err != nil { | ||
return nil, errors.Wrap(err, "could not create secretmanager client") | ||
} | ||
|
||
grabber := secretClient{ | ||
client: client, | ||
project: project, | ||
ctx: ctx, | ||
} | ||
|
||
return &grabber, nil | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
// Package gcpsecretfetch is a utility library for getting secrets from GCP Secret Manager. | ||
package gcpsecretfetch | ||
|
||
import ( | ||
"fmt" | ||
"github.com/pkg/errors" | ||
secretmanagerpb "google.golang.org/genproto/googleapis/cloud/secretmanager/v1" | ||
) | ||
|
||
func (svc *secretClient) UpdateSecrets(secrets map[string]string, disablePrior bool) error { | ||
for k, v := range secrets { | ||
if err := svc.updateSingleVersion(k, v, disablePrior); err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func (svc *secretClient) updateSingleVersion(secretName string, secretValue string, disablePrior bool) error { | ||
versions, err := svc.listVersions(secretName) | ||
if err != nil { | ||
return err | ||
} | ||
_, err = svc.addVersion(secretName, secretValue) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if disablePrior { | ||
return svc.deletePrior(versions) | ||
} | ||
return nil | ||
} | ||
|
||
func (svc *secretClient) addVersion(name string, value string) (*secretmanagerpb.SecretVersion, error) { | ||
|
||
// Declare the payload to store. | ||
payload := []byte(value) | ||
|
||
// Build the request. | ||
|
||
addSecretVersionReq := &secretmanagerpb.AddSecretVersionRequest{ | ||
Parent: fmt.Sprintf("projects/%s/secrets/%s", svc.project, name), | ||
Payload: &secretmanagerpb.SecretPayload{ | ||
Data: payload, | ||
}, | ||
} | ||
|
||
// Call the API. | ||
version, err := svc.client.AddSecretVersion(svc.ctx, addSecretVersionReq) | ||
if err != nil { | ||
return nil, errors.Wrap(err, "failed to add secret version: "+addSecretVersionReq.String()) | ||
} | ||
return version, nil | ||
} | ||
|
||
func (svc *secretClient) getSecret(name string) (*secretmanagerpb.Secret, error) { | ||
getSecretReq := &secretmanagerpb.GetSecretRequest{ | ||
Name: fmt.Sprintf("projects/%s/secrets/%s", svc.project, name), | ||
} | ||
|
||
secret, err := svc.client.GetSecret(svc.ctx, getSecretReq) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return secret, nil | ||
} | ||
|
||
func (svc *secretClient) getLatestSecretVersion(name string) (*secretmanagerpb.SecretVersion, error) { | ||
req := &secretmanagerpb.GetSecretVersionRequest{ | ||
Name: fmt.Sprintf("projects/%s/secrets/%s/versions/latest", svc.project, name), | ||
} | ||
|
||
secret, err := svc.client.GetSecretVersion(svc.ctx, req) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return secret, nil | ||
} | ||
|
||
func (svc *secretClient) listVersions(name string) ([]*secretmanagerpb.SecretVersion, error) { | ||
req := &secretmanagerpb.ListSecretVersionsRequest{ | ||
PageSize: 1000, | ||
Parent: fmt.Sprintf("projects/%s/secrets/%s", svc.project, name), | ||
} | ||
|
||
versions := svc.client.ListSecretVersions(svc.ctx, req) | ||
|
||
var output []*secretmanagerpb.SecretVersion | ||
|
||
for { | ||
if version, err := versions.Next(); err != nil { | ||
if err.Error() == "no more items in iterator" { | ||
break | ||
} else { | ||
return nil, err | ||
} | ||
} else { | ||
output = append(output, version) | ||
} | ||
} | ||
|
||
return output, nil | ||
} | ||
|
||
func (svc *secretClient) deletePrior(versions []*secretmanagerpb.SecretVersion) error { | ||
for _, v := range versions { | ||
req := &secretmanagerpb.DestroySecretVersionRequest{Name: v.Name} | ||
_, err := svc.client.DestroySecretVersion(svc.ctx, req) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} |