pkg/vault/kv/v1_service.go (83 lines of code) (raw):

// Licensed to Elasticsearch B.V. under one or more contributor // license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright // ownership. Elasticsearch B.V. licenses this file to you 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 // // http://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 kv import ( "context" "fmt" "github.com/elastic/harp/pkg/vault/logical" vpath "github.com/elastic/harp/pkg/vault/path" ) type kvv1Backend struct { logical logical.Logical mountPath string } // V1 returns a K/V v1 backend service instance. func V1(l logical.Logical, mountPath string) Service { return &kvv1Backend{ logical: l, mountPath: mountPath, } } //nolint:revive // refactor use of ctx func (s *kvv1Backend) List(ctx context.Context, path string) ([]string, error) { // Clean path first secretPath := vpath.SanitizePath(path) if secretPath == "" { return nil, fmt.Errorf("unable to query with empty path") } // Create logical client secret, err := s.logical.List(secretPath) if err != nil { return nil, fmt.Errorf("unable to list secret keys: %w", err) } if secret == nil { // Path is a leaf return nil, nil } if secret.Data == nil { return nil, fmt.Errorf("invalid secret response") } // Check required property k, ok := secret.Data["keys"] if !ok || k == nil { return nil, fmt.Errorf("invalid response missing 'keys' property") } // Check value type r, ok := k.([]interface{}) if !ok { return nil, fmt.Errorf("invalid response 'keys' is not a list (%T)", k) } // Convert list of interface to list of string out := make([]string, len(r)) for i := range r { out[i] = fmt.Sprintf("%v", r[i]) } // No error return out, nil } //nolint:revive // refactor use of ctx func (s *kvv1Backend) Read(ctx context.Context, path string) (SecretData, SecretMetadata, error) { // Clean path first secretPath := vpath.SanitizePath(path) if secretPath == "" { return nil, nil, fmt.Errorf("unable to query with empty path") } // Create a logical client secret, err := s.logical.Read(secretPath) if err != nil { return nil, nil, fmt.Errorf("unable to retrieve secret for path '%s': %w", path, err) } if secret == nil { return nil, nil, fmt.Errorf("unable to retrieve secret for path '%s': %w", path, ErrPathNotFound) } if secret.Data == nil { return nil, nil, fmt.Errorf("unable to retrieve secret for path '%s': %w", path, ErrNoData) } // Return secret value and no error return secret.Data, nil, err } //nolint:revive // refactor use of version func (s *kvv1Backend) ReadVersion(ctx context.Context, path string, version uint32) (SecretData, SecretMetadata, error) { return s.Read(ctx, path) } func (s *kvv1Backend) Write(ctx context.Context, path string, data SecretData) error { return s.WriteWithMeta(ctx, path, data, nil) } //nolint:revive // refactor use of ctx func (s *kvv1Backend) WriteWithMeta(ctx context.Context, path string, data SecretData, meta SecretMetadata) error { // Clean path first secretPath := vpath.SanitizePath(path) if secretPath == "" { return fmt.Errorf("unable to query with empty path") } // Add metadata as secret data. if len(meta) > 0 { data[VaultMetadataDataKey] = meta } // Create a logical client _, err := s.logical.Write(secretPath, data) if err != nil { return fmt.Errorf("unable to write secret data for path '%s': %w", path, err) } return nil }