Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract support for SDKMS provider #3237

Merged
merged 2 commits into from Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 27 additions & 4 deletions docs/provider/fortanix.md
Expand Up @@ -26,6 +26,7 @@ spec:
### Referencing Secrets

```yaml
# Raw stored value
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
Expand All @@ -36,15 +37,37 @@ spec:
kind: SecretStore
name: secret-store
data:

# Raw stored value
- secretKey: <KEY_IN_KUBE_SECRET>
remoteRef:
key: <SDKMS_SECURITY_OBJECT_NAME>

# From stored key-value JSON
---
# From stored key-value JSON
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: secret-from-property
spec:
refreshInterval: 1h
secretStoreRef:
kind: SecretStore
name: secret-store
data:
- secretKey: <KEY_IN_KUBE_SECRET>
remoteRef:
key: <SDKMS_SECURITY_OBJECT_NAME>
property: <SECURITY_OBJECT_VALUE_INNER_PROPERTY>
---
# Extract all keys from stored key-value JSON
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: secret-from-extract
spec:
refreshInterval: 1h
secretStoreRef:
kind: SecretStore
name: secret-store
dataFrom:
- extract:
key: <SDKMS_SECURITY_OBJECT_NAME>
```
27 changes: 22 additions & 5 deletions pkg/provider/fortanix/fortanix.go
Expand Up @@ -35,7 +35,6 @@ const (
errDeleteSecretsNotSupported = "deleting secrets is currently not supported"
errUnmarshalSecret = "unable to unmarshal secret, is it a valid JSON?: %w"
errUnableToGetValue = "unable to get value for key %s"
errGettingSecretMapNotSupported = "getting secret map is currently not supported"
errGettingAllSecretsNotSupported = "getting all secrets is currently not supported"
)

Expand Down Expand Up @@ -74,6 +73,28 @@ func (c *client) GetSecret(ctx context.Context, ref esv1beta1.ExternalSecretData
return utils.GetByteValue(value)
}

func (c *client) GetSecretMap(ctx context.Context, ref esv1beta1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
RecuencoJones marked this conversation as resolved.
Show resolved Hide resolved
data, err := c.GetSecret(ctx, ref)

RecuencoJones marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, err
}

kv := make(map[string]string)
err = json.Unmarshal(data, &kv)

RecuencoJones marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, fmt.Errorf(errUnmarshalSecret, err)
}

secretData := make(map[string][]byte)
RecuencoJones marked this conversation as resolved.
Show resolved Hide resolved
for k, v := range kv {
secretData[k] = []byte(v)
}

return secretData, nil
}

func (c *client) PushSecret(_ context.Context, _ *corev1.Secret, _ esv1beta1.PushSecretData) error {
return errors.New(errPushSecretsNotSupported)
}
Expand All @@ -86,10 +107,6 @@ func (c *client) Validate() (esv1beta1.ValidationResult, error) {
return esv1beta1.ValidationResultReady, nil
}

func (c *client) GetSecretMap(_ context.Context, _ esv1beta1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
return nil, errors.New(errGettingSecretMapNotSupported)
}

func (c *client) GetAllSecrets(_ context.Context, _ esv1beta1.ExternalSecretFind) (map[string][]byte, error) {
return nil, errors.New(errGettingAllSecretsNotSupported)
}
Expand Down
51 changes: 44 additions & 7 deletions pkg/provider/fortanix/fortanix_test.go
Expand Up @@ -27,6 +27,12 @@ import (
esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
)

var (
securityObjectID = "id"
securityObjectName = "securityObjectName"
securityObjectUser = "user"
)

func newTestClient(t *testing.T, handler func(w http.ResponseWriter, r *http.Request)) *client {
const apiKey = "api-key"

Expand Down Expand Up @@ -56,14 +62,11 @@ type testSecurityObjectValue struct {

func TestGetOpaqueSecurityObject(t *testing.T) {
ctx := context.Background()
securityObjectName := "securityObjectName"

securityObjectValue := toJSON(t, testSecurityObjectValue{
Property: "value",
})

securityObjectUser := "user"

securityObject := sdkms.Sobject{
Creator: sdkms.Principal{
User: &securityObjectUser,
Expand Down Expand Up @@ -103,15 +106,11 @@ func TestGetOpaqueSecurityObject(t *testing.T) {

func TestGetSecretSecurityObject(t *testing.T) {
ctx := context.Background()
securityObjectName := "securityObjectName"
securityObjectID := "id"

securityObjectValue := toJSON(t, testSecurityObjectValue{
Property: "value",
})

securityObjectUser := "user"

securityObject := sdkms.Sobject{
Creator: sdkms.Principal{
User: &securityObjectUser,
Expand Down Expand Up @@ -150,3 +149,41 @@ func TestGetSecretSecurityObject(t *testing.T) {
assert.Equal(t, []byte(`value`), got)
})
}

func TestDataFromExtract(t *testing.T) {
ctx := context.Background()

securityObjectValue := toJSON(t, testSecurityObjectValue{
Property: "value",
})

securityObject := sdkms.Sobject{
Creator: sdkms.Principal{
User: &securityObjectUser,
},
Name: &securityObjectName,
Kid: &securityObjectID,
Value: &securityObjectValue,
ObjType: sdkms.ObjectTypeSecret,
}

client := newTestClient(t, func(w http.ResponseWriter, r *http.Request) {
err := json.NewEncoder(w).Encode(securityObject)
require.NoError(t, err)
})

t.Run("extract data from secret security object", func(t *testing.T) {
ref := esv1beta1.ExternalSecretDataRemoteRef{
Key: securityObjectName,
}

got, err := client.GetSecretMap(ctx, ref)

assert.NoError(t, err)

for k, v := range got {
assert.Equal(t, "property", k)
assert.Equal(t, []byte(`value`), v)
}
})
}