github.com/replicatedhq/ship@v0.55.0/pkg/lifecycle/render/terraform/render.go (about)

     1  package terraform
     2  
     3  import (
     4  	"context"
     5  	"path"
     6  
     7  	"github.com/go-kit/kit/log"
     8  	"github.com/pkg/errors"
     9  	"github.com/replicatedhq/libyaml"
    10  	"github.com/replicatedhq/ship/pkg/api"
    11  	"github.com/replicatedhq/ship/pkg/lifecycle/render/inline"
    12  	"github.com/replicatedhq/ship/pkg/lifecycle/render/root"
    13  	"github.com/spf13/afero"
    14  )
    15  
    16  // Renderer is something that can render a terraform asset as part of a planner.Plan
    17  type Renderer interface {
    18  	Execute(
    19  		rootFs root.Fs,
    20  		asset api.TerraformAsset,
    21  		meta api.ReleaseMetadata,
    22  		templateContext map[string]interface{},
    23  		configGroups []libyaml.ConfigGroup,
    24  	) func(ctx context.Context) error
    25  }
    26  
    27  // a LocalRenderer renders a terraform asset by vendoring in terraform source code
    28  type LocalRenderer struct {
    29  	Logger log.Logger
    30  	Inline inline.Renderer
    31  	Fs     afero.Afero
    32  }
    33  
    34  var _ Renderer = &LocalRenderer{}
    35  
    36  func NewRenderer(
    37  	logger log.Logger,
    38  	inline inline.Renderer,
    39  	fs afero.Afero,
    40  ) Renderer {
    41  	return &LocalRenderer{
    42  		Logger: logger,
    43  		Inline: inline,
    44  		Fs:     fs,
    45  	}
    46  }
    47  
    48  func (r *LocalRenderer) Execute(
    49  	rootFs root.Fs,
    50  	asset api.TerraformAsset,
    51  	meta api.ReleaseMetadata,
    52  	templateContext map[string]interface{},
    53  	configGroups []libyaml.ConfigGroup,
    54  ) func(ctx context.Context) error {
    55  	return func(ctx context.Context) error {
    56  
    57  		if asset.Inline == "" {
    58  			return errors.New("online \"inline\" terraform assets are supported")
    59  		}
    60  
    61  		assetsPath := "main.tf"
    62  		if asset.Dest != "" && path.Ext(asset.Dest) == ".tf" {
    63  			assetsPath = asset.Dest
    64  		}
    65  
    66  		// write the inline spec
    67  		err := r.Inline.Execute(
    68  			rootFs,
    69  			api.InlineAsset{
    70  				Contents: asset.Inline,
    71  				AssetShared: api.AssetShared{
    72  					Dest: assetsPath,
    73  					Mode: asset.Mode,
    74  				},
    75  			},
    76  			meta,
    77  			templateContext,
    78  			configGroups,
    79  		)(ctx)
    80  
    81  		if err != nil {
    82  			return errors.Wrap(err, "write tf config")
    83  		}
    84  		return nil
    85  	}
    86  }