github.com/zntrio/harp/v2@v2.0.9/pkg/tasks/to/kv.go (about)

     1  // Licensed to Elasticsearch B.V. under one or more contributor
     2  // license agreements. See the NOTICE file distributed with
     3  // this work for additional information regarding copyright
     4  // ownership. Elasticsearch B.V. licenses this file to you under
     5  // the Apache License, Version 2.0 (the "License"); you may
     6  // not use this file except in compliance with the License.
     7  // You may obtain a copy of the License at
     8  //
     9  //     http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing,
    12  // software distributed under the License is distributed on an
    13  // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    14  // KIND, either express or implied.  See the License for the
    15  // specific language governing permissions and limitations
    16  // under the License.
    17  
    18  package to
    19  
    20  import (
    21  	"context"
    22  	"encoding/json"
    23  	"fmt"
    24  	"path"
    25  
    26  	"github.com/zntrio/harp/v2/pkg/bundle"
    27  	"github.com/zntrio/harp/v2/pkg/kv"
    28  	"github.com/zntrio/harp/v2/pkg/tasks"
    29  )
    30  
    31  type PublishKVTask struct {
    32  	_               struct{}
    33  	ContainerReader tasks.ReaderProvider
    34  	Store           kv.Store
    35  	SecretAsKey     bool
    36  	Prefix          string
    37  }
    38  
    39  func (t *PublishKVTask) Run(ctx context.Context) error {
    40  	// Create the reader
    41  	reader, err := t.ContainerReader(ctx)
    42  	if err != nil {
    43  		return fmt.Errorf("unable to open input bundle reader: %w", err)
    44  	}
    45  
    46  	// Extract bundle from container
    47  	b, err := bundle.FromContainerReader(reader)
    48  	if err != nil {
    49  		return fmt.Errorf("unable to load bundle: %w", err)
    50  	}
    51  
    52  	// Convert as map
    53  	bundleMap, err := bundle.AsMap(b)
    54  	if err != nil {
    55  		return fmt.Errorf("unable to transform the bundle as a map: %w", err)
    56  	}
    57  
    58  	// Foreach element in the bundle map.
    59  	for key, value := range bundleMap {
    60  		if t.Prefix != "" {
    61  			key = path.Join(path.Clean(t.Prefix), key)
    62  		}
    63  		if !t.SecretAsKey {
    64  			// Encode as json
    65  			payload, err := json.Marshal(value)
    66  			if err != nil {
    67  				return fmt.Errorf("unable to encode value as JSON for %q: %w", key, err)
    68  			}
    69  
    70  			// Insert in KV store.
    71  			if err := t.Store.Put(ctx, key, payload); err != nil {
    72  				return fmt.Errorf("unable to publish %q secret in store: %w", key, err)
    73  			}
    74  		} else {
    75  			// Range over secrets
    76  			secrets, ok := value.(bundle.KV)
    77  			if !ok {
    78  				continue
    79  			}
    80  
    81  			// Publish each secret as a leaf.
    82  			for secKey, secValue := range secrets {
    83  				// Insert in KV store.
    84  				if err := t.Store.Put(ctx, path.Join(key, secKey), []byte(fmt.Sprintf("%v", secValue))); err != nil {
    85  					return fmt.Errorf("unable to publish %q secret in store: %w", key, err)
    86  				}
    87  			}
    88  		}
    89  	}
    90  
    91  	// No error
    92  	return nil
    93  }