github.com/zntrio/harp/v2@v2.0.9/pkg/bundle/template/visitor/secretbuilder/api.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  	"errors"
    22  	"fmt"
    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  	"github.com/zntrio/harp/v2/pkg/template/engine"
    27  )
    28  
    29  // New returns a secret builder visitor instance.
    30  func New(result *bundlev1.Bundle, templateCtx engine.Context) visitor.TemplateVisitor {
    31  	return &secretBuilder{
    32  		bundle:          result,
    33  		templateContext: templateCtx,
    34  	}
    35  }
    36  
    37  // -----------------------------------------------------------------------------
    38  
    39  type secretBuilder struct {
    40  	bundle          *bundlev1.Bundle
    41  	templateContext engine.Context
    42  	err             error
    43  }
    44  
    45  //nolint:gocyclo,gocognit,funlen // refactoring later
    46  func (sb *secretBuilder) Visit(t *bundlev1.Template) {
    47  	results := make(chan *bundlev1.Package)
    48  
    49  	// Check arguments
    50  	if t == nil {
    51  		sb.err = errors.New("template is nil")
    52  		return
    53  	}
    54  	if t.Spec == nil {
    55  		sb.err = errors.New("template spec nil")
    56  		return
    57  	}
    58  	if t.Spec.Namespaces == nil {
    59  		sb.err = errors.New("template spec namespace nil")
    60  		return
    61  	}
    62  
    63  	go func() {
    64  		defer close(results)
    65  
    66  		// Infrastructure secrets
    67  		if t.Spec.Namespaces.Infrastructure != nil {
    68  			for _, obj := range t.Spec.Namespaces.Infrastructure {
    69  				// Initialize a infrastructure visitor
    70  				v := infrastructure(results, sb.templateContext)
    71  
    72  				// Traverse the object-tree
    73  				visitor.InfrastructureDecorator(obj).Accept(v)
    74  
    75  				// Get result
    76  				if err := v.Error(); err != nil {
    77  					sb.err = err
    78  					return
    79  				}
    80  			}
    81  		}
    82  
    83  		// Platform secrets
    84  		if t.Spec.Namespaces.Platform != nil {
    85  			for _, obj := range t.Spec.Namespaces.Platform {
    86  				// Check selector
    87  				if t.Spec.Selector == nil {
    88  					sb.err = fmt.Errorf("selector is mandatory for platform secrets")
    89  					return
    90  				}
    91  
    92  				// Initialize a infrastructure visitor
    93  				v, err := platform(results, sb.templateContext, t.Spec.Selector.Quality, t.Spec.Selector.Platform)
    94  				if err != nil {
    95  					sb.err = err
    96  					return
    97  				}
    98  
    99  				// Traverse the object-tree
   100  				visitor.PlatformDecorator(obj).Accept(v)
   101  
   102  				// Get result
   103  				if err := v.Error(); err != nil {
   104  					sb.err = err
   105  					return
   106  				}
   107  			}
   108  		}
   109  
   110  		// Product secrets
   111  		if t.Spec.Namespaces.Product != nil {
   112  			for _, obj := range t.Spec.Namespaces.Product {
   113  				// Check selector
   114  				if t.Spec.Selector == nil {
   115  					sb.err = fmt.Errorf("selector is mandatory for product secrets")
   116  					return
   117  				}
   118  
   119  				// Initialize a infrastructure visitor
   120  				v, err := product(results, sb.templateContext, t.Spec.Selector.Product, t.Spec.Selector.Version)
   121  				if err != nil {
   122  					sb.err = err
   123  					return
   124  				}
   125  
   126  				// Traverse the object-tree
   127  				visitor.ProductDecorator(obj).Accept(v)
   128  
   129  				// Get result
   130  				if err := v.Error(); err != nil {
   131  					sb.err = err
   132  					return
   133  				}
   134  			}
   135  		}
   136  
   137  		// Application secrets
   138  		if t.Spec.Namespaces.Application != nil {
   139  			for _, obj := range t.Spec.Namespaces.Application {
   140  				// Check selector
   141  				if t.Spec.Selector == nil {
   142  					sb.err = fmt.Errorf("selector is mandatory for application secrets")
   143  					return
   144  				}
   145  
   146  				// Initialize a infrastructure visitor
   147  				v, err := application(results, sb.templateContext, t.Spec.Selector.Quality, t.Spec.Selector.Platform, t.Spec.Selector.Product, t.Spec.Selector.Version)
   148  				if err != nil {
   149  					sb.err = err
   150  					return
   151  				}
   152  
   153  				// Traverse the object-tree
   154  				visitor.ApplicationDecorator(obj).Accept(v)
   155  
   156  				// Get result
   157  				if err := v.Error(); err != nil {
   158  					sb.err = err
   159  					return
   160  				}
   161  			}
   162  		}
   163  	}()
   164  
   165  	// Pull all packages
   166  	for p := range results {
   167  		sb.bundle.Packages = append(sb.bundle.Packages, p)
   168  	}
   169  }
   170  
   171  func (sb *secretBuilder) Error() error {
   172  	return sb.err
   173  }