github.com/zntrio/harp/v2@v2.0.9/pkg/bundle/template/visitor/secretbuilder/product.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 secretbuilder
    19  
    20  import (
    21  	"fmt"
    22  	"strings"
    23  
    24  	bundlev1 "github.com/zntrio/harp/v2/api/gen/go/harp/bundle/v1"
    25  	"github.com/zntrio/harp/v2/pkg/bundle/template/visitor"
    26  	csov1 "github.com/zntrio/harp/v2/pkg/cso/v1"
    27  	"github.com/zntrio/harp/v2/pkg/template/engine"
    28  )
    29  
    30  type productSecretBuilder struct {
    31  	results         chan *bundlev1.Package
    32  	templateContext engine.Context
    33  
    34  	// Context
    35  	name      string
    36  	version   string
    37  	component string
    38  	err       error
    39  }
    40  
    41  // -----------------------------------------------------------------------------
    42  
    43  // Infrastructure returns a visitor instance to generate secretpath
    44  // and values.
    45  func product(results chan *bundlev1.Package, templateContext engine.Context, name, version string) (visitor.ProductVisitor, error) {
    46  	// Parse selector values
    47  	productName, err := engine.RenderContext(templateContext, name)
    48  	if err != nil {
    49  		return nil, fmt.Errorf("unable to render product.name: %w", err)
    50  	}
    51  	if strings.TrimSpace(productName) == "" {
    52  		return nil, fmt.Errorf("product selector must not be empty")
    53  	}
    54  
    55  	productVersion, err := engine.RenderContext(templateContext, version)
    56  	if err != nil {
    57  		return nil, fmt.Errorf("unable to render product.version: %w", err)
    58  	}
    59  	if strings.TrimSpace(productVersion) == "" {
    60  		return nil, fmt.Errorf("version selector must not be empty")
    61  	}
    62  
    63  	return &productSecretBuilder{
    64  		results:         results,
    65  		templateContext: templateContext,
    66  		name:            productName,
    67  		version:         productVersion,
    68  	}, nil
    69  }
    70  
    71  // -----------------------------------------------------------------------------
    72  
    73  func (b *productSecretBuilder) Error() error {
    74  	return b.err
    75  }
    76  
    77  func (b *productSecretBuilder) VisitForComponent(obj *bundlev1.ProductComponentNS) {
    78  	// Check arguments
    79  	if obj == nil {
    80  		return
    81  	}
    82  
    83  	// Set context values
    84  	b.component, b.err = engine.RenderContext(b.templateContext, obj.Name)
    85  	if b.err != nil {
    86  		return
    87  	}
    88  
    89  	for _, item := range obj.Secrets {
    90  		// Check arguments
    91  		if item == nil {
    92  			continue
    93  		}
    94  
    95  		// Parse suffix with template engine
    96  		suffix, err := engine.RenderContext(b.templateContext, item.Suffix)
    97  		if err != nil {
    98  			b.err = fmt.Errorf("unable to merge template is suffix %q", item.Suffix)
    99  			return
   100  		}
   101  
   102  		// Generate secret suffix
   103  		secretPath, err := csov1.RingProduct.Path(b.name, b.version, b.component, suffix)
   104  		if err != nil {
   105  			b.err = err
   106  			return
   107  		}
   108  
   109  		// Prepare template model
   110  		tmplModel := &struct {
   111  			Name      string
   112  			Version   string
   113  			Component string
   114  			Secret    *bundlev1.SecretSuffix
   115  		}{
   116  			Name:      b.name,
   117  			Version:   b.version,
   118  			Component: b.component,
   119  			Secret:    item,
   120  		}
   121  
   122  		// Compile template
   123  		p, err := parseSecretTemplate(b.templateContext, secretPath, item, tmplModel)
   124  		if err != nil {
   125  			b.err = err
   126  			return
   127  		}
   128  
   129  		// Add package to collection
   130  		b.results <- p
   131  	}
   132  }