k8s.io/test-infra@v0.0.0-20240520184403-27c6b4c223d8/gencred/pkg/secretmanager/secretmanager.go (about) 1 /* 2 Copyright 2021 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package secretmanager 18 19 import ( 20 "context" 21 "fmt" 22 23 secretmanager "cloud.google.com/go/secretmanager/apiv1" 24 "cloud.google.com/go/secretmanager/apiv1/secretmanagerpb" 25 "google.golang.org/api/iterator" 26 ) 27 28 // Client is a wrapper of secretmanager client 29 type Client struct { 30 // ProjectID is GCP project in which to store secrets in Secret Manager. 31 ProjectID string 32 client *secretmanager.Client 33 dryrun bool 34 } 35 36 // ClientInterface is the interface for manipulating secretmanager 37 type ClientInterface interface { 38 CreateSecret(ctx context.Context, secretID string) (*secretmanagerpb.Secret, error) 39 AddSecretVersion(ctx context.Context, secretName string, payload []byte) error 40 ListSecrets(ctx context.Context) ([]*secretmanagerpb.Secret, error) 41 } 42 43 // NewClient creates a client for secretmanager, it would fail if not authenticated 44 func NewClient(projectID string, dryrun bool) (*Client, error) { 45 // Create the client. 46 ctx := context.Background() 47 client, err := secretmanager.NewClient(ctx) 48 if err != nil { 49 return nil, fmt.Errorf("failed to setup client: %w", err) 50 } 51 return &Client{ProjectID: projectID, client: client, dryrun: dryrun}, nil 52 } 53 54 // CreateSecret creates a secret 55 func (c *Client) CreateSecret(ctx context.Context, secretID string) (*secretmanagerpb.Secret, error) { 56 if c.dryrun { 57 return nil, nil 58 } 59 // Create the request to create the secret. 60 createSecretReq := &secretmanagerpb.CreateSecretRequest{ 61 Parent: fmt.Sprintf("projects/%s", c.ProjectID), 62 SecretId: secretID, 63 Secret: &secretmanagerpb.Secret{ 64 Replication: &secretmanagerpb.Replication{ 65 Replication: &secretmanagerpb.Replication_Automatic_{ 66 Automatic: &secretmanagerpb.Replication_Automatic{}, 67 }, 68 }, 69 }, 70 } 71 72 return c.client.CreateSecret(ctx, createSecretReq) 73 } 74 75 // AddSecretVersion adds a secret version, aka update the value of a secret 76 func (c *Client) AddSecretVersion(ctx context.Context, secretName string, payload []byte) error { 77 if c.dryrun { 78 return nil 79 } 80 // Build the request. 81 addSecretVersionReq := &secretmanagerpb.AddSecretVersionRequest{ 82 Parent: fmt.Sprintf("projects/%s/secrets/%s", c.ProjectID, secretName), 83 Payload: &secretmanagerpb.SecretPayload{ 84 Data: payload, 85 }, 86 } 87 88 // Call the API. 89 _, err := c.client.AddSecretVersion(ctx, addSecretVersionReq) 90 return err 91 } 92 93 // ListSecrets lists all secrets under current project 94 func (c *Client) ListSecrets(ctx context.Context) ([]*secretmanagerpb.Secret, error) { 95 var res []*secretmanagerpb.Secret 96 // Build the request. 97 listRequest := &secretmanagerpb.ListSecretsRequest{ 98 Parent: fmt.Sprintf("projects/%s", c.ProjectID), 99 } 100 101 // Call the API. 102 it := c.client.ListSecrets(ctx, listRequest) 103 for { 104 s, err := it.Next() 105 if err != nil { 106 if err == iterator.Done { 107 break 108 } 109 return nil, err 110 } 111 res = append(res, s) 112 } 113 return res, nil 114 }