| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- /*
- Copyright © 2025 ESO Maintainer Team
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- https://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package volcengine
- import (
- "context"
- "encoding/json"
- "errors"
- "fmt"
- "github.com/volcengine/volcengine-go-sdk/service/kms"
- corev1 "k8s.io/api/core/v1"
- esapi "github.com/external-secrets/external-secrets/apis/externalsecrets/v1"
- )
- const (
- notImplemented = "not implemented"
- )
- var _ esapi.SecretsClient = &Client{}
- // Client is a client for the Volcengine provider.
- type Client struct {
- kms kms.KMSAPI
- }
- // NewClient creates a new Volcengine client.
- func NewClient(kms kms.KMSAPI) *Client {
- return &Client{
- kms: kms,
- }
- }
- // GetSecret retrieves a secret value from Volcengine Secrets Manager.
- func (c *Client) GetSecret(ctx context.Context, ref esapi.ExternalSecretDataRemoteRef) ([]byte, error) {
- return c.getSecretValue(ctx, ref)
- }
- // SecretExists checks if a secret exists in Volcengine Secrets Manager.
- func (c *Client) SecretExists(ctx context.Context, remoteRef esapi.PushSecretRemoteRef) (bool, error) {
- secretName := remoteRef.GetRemoteKey()
- if secretName == "" {
- return false, errors.New("secret name is empty")
- }
- _, err := c.kms.DescribeSecretWithContext(ctx, &kms.DescribeSecretInput{
- SecretName: &secretName,
- })
- if err != nil {
- return false, err
- }
- return true, nil
- }
- // Validate checks if the provider is configured correctly.
- func (c *Client) Validate() (esapi.ValidationResult, error) {
- if c.kms != nil {
- return esapi.ValidationResultReady, nil
- }
- return esapi.ValidationResultError, errors.New("kms client is not initialized")
- }
- // GetSecretMap retrieves a secret value and unmarshals it as a map.
- func (c *Client) GetSecretMap(ctx context.Context, ref esapi.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
- value, err := c.getSecretValue(ctx, ref)
- if err != nil {
- return nil, err
- }
- var rawSecretMap map[string]json.RawMessage
- if err := json.Unmarshal(value, &rawSecretMap); err != nil {
- return nil, fmt.Errorf("failed to unmarshal secret: %w", err)
- }
- secretMap := make(map[string][]byte, len(rawSecretMap))
- for key, value := range rawSecretMap {
- secretMap[key] = []byte(value)
- }
- return secretMap, nil
- }
- // GetAllSecrets retrieves all secrets matching the given criteria.
- func (c *Client) GetAllSecrets(ctx context.Context, ref esapi.ExternalSecretFind) (map[string][]byte, error) {
- return nil, errors.New(notImplemented)
- }
- // PushSecret creates or updates a secret in Volcengine Secrets Manager.
- func (c *Client) PushSecret(ctx context.Context, secret *corev1.Secret, data esapi.PushSecretData) error {
- return errors.New(notImplemented)
- }
- // DeleteSecret deletes a secret from Volcengine Secrets Manager.
- func (c *Client) DeleteSecret(ctx context.Context, remoteRef esapi.PushSecretRemoteRef) error {
- return errors.New(notImplemented)
- }
- // Close is a no-op for the Volcengine client.
- func (c *Client) Close(_ context.Context) error {
- return nil
- }
- func (c *Client) getSecretValue(ctx context.Context, ref esapi.ExternalSecretDataRemoteRef) ([]byte, error) {
- output, err := c.kms.GetSecretValueWithContext(ctx, &kms.GetSecretValueInput{
- SecretName: &ref.Key,
- VersionID: resolveVersion(ref),
- })
- if err != nil {
- return nil, err
- }
- if output.SecretValue == nil {
- return nil, fmt.Errorf("secret %s has no value", ref.Key)
- }
- secret := []byte(*output.SecretValue)
- if ref.Property == "" {
- return secret, nil
- }
- return extractProperty(secret, ref.Property)
- }
- func extractProperty(secret []byte, property string) ([]byte, error) {
- var secretMap map[string]json.RawMessage
- if err := json.Unmarshal(secret, &secretMap); err != nil {
- return nil, fmt.Errorf("failed to unmarshal secret: %w", err)
- }
- value, ok := secretMap[property]
- if !ok {
- return nil, fmt.Errorf("property %q not found in secret", property)
- }
- var s string
- if json.Unmarshal(value, &s) == nil {
- return []byte(s), nil
- }
- return value, nil
- }
- func resolveVersion(ref esapi.ExternalSecretDataRemoteRef) *string {
- if ref.Version != "" {
- return &ref.Version
- }
- return nil
- }
|