Skip to content

Commit d6d2d9a

Browse files
committed
Allow injecting custom client options for AWS, Azure and GCP
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
1 parent 2356626 commit d6d2d9a

3 files changed

Lines changed: 47 additions & 2 deletions

File tree

azkv/keysource.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ type MasterKey struct {
6060
// using TokenCredential.ApplyToMasterKey.
6161
// If nil, azidentity.NewDefaultAzureCredential is used.
6262
tokenCredential azcore.TokenCredential
63+
// clientOptions contains the azkeys.ClientOptions used by the Azure client.
64+
clientOptions *azkeys.ClientOptions
6365
}
6466

6567
// NewMasterKey creates a new MasterKey from a URL, key name and version,
@@ -118,6 +120,17 @@ func (t TokenCredential) ApplyToMasterKey(key *MasterKey) {
118120
key.tokenCredential = t.token
119121
}
120122

123+
// ClientOptions is a wrapper around azkeys.ClientOptions to allow
124+
// configuration of the Azure Key Vault client.
125+
type ClientOptions struct {
126+
o *azkeys.ClientOptions
127+
}
128+
129+
// ApplyToMasterKey configures the ClientOptions on the provided key.
130+
func (c ClientOptions) ApplyToMasterKey(key *MasterKey) {
131+
key.clientOptions = c.o
132+
}
133+
121134
// Encrypt takes a SOPS data key, encrypts it with Azure Key Vault, and stores
122135
// the result in the EncryptedKey field.
123136
func (key *MasterKey) Encrypt(dataKey []byte) error {
@@ -182,7 +195,7 @@ func (key *MasterKey) Decrypt() ([]byte, error) {
182195
return nil, fmt.Errorf("failed to base64 decode Azure Key Vault encrypted key: %w", err)
183196
}
184197

185-
c, err := azkeys.NewClient(key.VaultURL, token, nil)
198+
c, err := azkeys.NewClient(key.VaultURL, token, key.clientOptions)
186199
if err != nil {
187200
log.WithFields(logrus.Fields{"key": key.Name, "version": key.Version}).Info("Decryption failed")
188201
return nil, fmt.Errorf("failed to construct Azure Key Vault client to decrypt data: %w", err)

gcpkms/keysource.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ type MasterKey struct {
6666
// Mostly useful for testing at present, to wire the client to a mock
6767
// server.
6868
grpcConn *grpc.ClientConn
69+
// grpcDialOpts are the gRPC dial options used to create the gRPC connection.
70+
grpcDialOpts []grpc.DialOption
6971
}
7072

7173
// NewMasterKeyFromResourceID creates a new MasterKey with the provided resource
@@ -116,6 +118,14 @@ func (c CredentialJSON) ApplyToMasterKey(key *MasterKey) {
116118
key.credentialJSON = c
117119
}
118120

121+
// DialOptions are the gRPC dial options used to create the gRPC connection.
122+
type DialOptions []grpc.DialOption
123+
124+
// ApplyToMasterKey configures the DialOptions on the provided key.
125+
func (d DialOptions) ApplyToMasterKey(key *MasterKey) {
126+
key.grpcDialOpts = d
127+
}
128+
119129
// Encrypt takes a SOPS data key, encrypts it with GCP KMS, and stores the
120130
// result in the EncryptedKey field.
121131
func (key *MasterKey) Encrypt(dataKey []byte) error {
@@ -261,8 +271,13 @@ func (key *MasterKey) newKMSClient() (*kms.KeyManagementClient, error) {
261271
}
262272
}
263273

264-
if key.grpcConn != nil {
274+
switch {
275+
case key.grpcConn != nil:
265276
opts = append(opts, option.WithGRPCConn(key.grpcConn))
277+
case len(key.grpcDialOpts) > 0:
278+
for _, opt := range key.grpcDialOpts {
279+
opts = append(opts, option.WithGRPCDialOption(opt))
280+
}
266281
}
267282

268283
ctx := context.Background()

kms/keysource.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"context"
1010
"encoding/base64"
1111
"fmt"
12+
"net/http"
1213
"os"
1314
"regexp"
1415
"sort"
@@ -79,6 +80,8 @@ type MasterKey struct {
7980
// injected using e.g. an environment variable. The field is not publicly
8081
// exposed, nor configurable.
8182
baseEndpoint string
83+
// httpClient is used to override the default HTTP client used by the AWS client.
84+
httpClient *http.Client
8285
}
8386

8487
// NewMasterKey creates a new MasterKey from an ARN, role and context, setting
@@ -233,6 +236,17 @@ func (c CredentialsProvider) ApplyToMasterKey(key *MasterKey) {
233236
key.credentialsProvider = c.provider
234237
}
235238

239+
// HTTPClient is a wrapper around http.Client used for configuring the
240+
// AWS KMS client.
241+
type HTTPClient struct {
242+
hc *http.Client
243+
}
244+
245+
// ApplyToMasterKey configures the HTTP client on the provided key.
246+
func (h HTTPClient) ApplyToMasterKey(key *MasterKey) {
247+
key.httpClient = h.hc
248+
}
249+
236250
// Encrypt takes a SOPS data key, encrypts it with KMS and stores the result
237251
// in the EncryptedKey field.
238252
func (key *MasterKey) Encrypt(dataKey []byte) error {
@@ -369,6 +383,9 @@ func (key MasterKey) createKMSConfig() (*aws.Config, error) {
369383
lo.SharedConfigProfile = key.AwsProfile
370384
}
371385
lo.Region = region
386+
if key.httpClient != nil {
387+
lo.HTTPClient = key.httpClient
388+
}
372389
return nil
373390
})
374391
if err != nil {

0 commit comments

Comments
 (0)