github.com/terraform-modules-krish/terratest@v0.29.0/modules/helm/template.go (about)

     1  package helm
     2  
     3  import (
     4  	"encoding/json"
     5  	"path/filepath"
     6  
     7  	"github.com/ghodss/yaml"
     8  	gruntwork-cli "github.com/terraform-modules-krish/go-commons/errors"
     9  	"github.com/stretchr/testify/require"
    10  
    11  	"github.com/terraform-modules-krish/terratest/modules/files"
    12  	"github.com/terraform-modules-krish/terratest/modules/testing"
    13  )
    14  
    15  // RenderTemplate runs `helm template` to render the template given the provided options and returns stdout/stderr from
    16  // the template command. If you pass in templateFiles, this will only render those templates. This function will fail
    17  // the test if there is an error rendering the template.
    18  func RenderTemplate(t testing.TestingT, options *Options, chartDir string, releaseName string, templateFiles []string, extraHelmArgs ...string) string {
    19  	out, err := RenderTemplateE(t, options, chartDir, releaseName, templateFiles, extraHelmArgs...)
    20  	require.NoError(t, err)
    21  	return out
    22  }
    23  
    24  // RenderTemplateE runs `helm template` to render the template given the provided options and returns stdout/stderr from
    25  // the template command. If you pass in templateFiles, this will only render those templates.
    26  func RenderTemplateE(t testing.TestingT, options *Options, chartDir string, releaseName string, templateFiles []string, extraHelmArgs ...string) (string, error) {
    27  	// First, verify the charts dir exists
    28  	absChartDir, err := filepath.Abs(chartDir)
    29  	if err != nil {
    30  		return "", errors.WithStackTrace(err)
    31  	}
    32  	if !files.FileExists(chartDir) {
    33  		return "", errors.WithStackTrace(ChartNotFoundError{chartDir})
    34  	}
    35  
    36  	// Now construct the args
    37  	// We first construct the template args
    38  	args := []string{}
    39  	if options.KubectlOptions != nil && options.KubectlOptions.Namespace != "" {
    40  		args = append(args, "--namespace", options.KubectlOptions.Namespace)
    41  	}
    42  	args, err = getValuesArgsE(t, options, args...)
    43  	if err != nil {
    44  		return "", err
    45  	}
    46  	for _, templateFile := range templateFiles {
    47  		// validate this is a valid template file
    48  		absTemplateFile := filepath.Join(absChartDir, templateFile)
    49  		if !files.FileExists(absTemplateFile) {
    50  			return "", errors.WithStackTrace(TemplateFileNotFoundError{Path: templateFile, ChartDir: absChartDir})
    51  		}
    52  
    53  		// Note: we only get the abs template file path to check it actually exists, but the `helm template` command
    54  		// expects the relative path from the chart.
    55  		args = append(args, "--show-only", templateFile)
    56  	}
    57  	// deal extraHelmArgs
    58  	args = append(args, extraHelmArgs...)
    59  
    60  	// ... and add the name and chart at the end as the command expects
    61  	args = append(args, releaseName, chartDir)
    62  
    63  	// Finally, call out to helm template command
    64  	return RunHelmCommandAndGetOutputE(t, options, "template", args...)
    65  }
    66  
    67  // UnmarshalK8SYaml is the same as UnmarshalK8SYamlE, but will fail the test if there is an error.
    68  func UnmarshalK8SYaml(t testing.TestingT, yamlData string, destinationObj interface{}) {
    69  	require.NoError(t, UnmarshalK8SYamlE(t, yamlData, destinationObj))
    70  }
    71  
    72  // UnmarshalK8SYamlE can be used to take template outputs and unmarshal them into the corresponding client-go struct. For
    73  // example, suppose you render the template into a Deployment object. You can unmarshal the yaml as follows:
    74  //
    75  // var deployment appsv1.Deployment
    76  // UnmarshalK8SYamlE(t, renderedOutput, &deployment)
    77  //
    78  // At the end of this, the deployment variable will be populated.
    79  func UnmarshalK8SYamlE(t testing.TestingT, yamlData string, destinationObj interface{}) error {
    80  	// NOTE: the client-go library can only decode json, so we will first convert the yaml to json before unmarshaling
    81  	jsonData, err := yaml.YAMLToJSON([]byte(yamlData))
    82  	if err != nil {
    83  		return errors.WithStackTrace(err)
    84  	}
    85  	err = json.Unmarshal(jsonData, destinationObj)
    86  	if err != nil {
    87  		return errors.WithStackTrace(err)
    88  	}
    89  	return nil
    90  }