github.com/GoogleCloudPlatform/terraformer@v0.8.18/terraformutils/terraformoutput/hcl.go (about)

     1  // Copyright 2018 The Terraformer Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  package terraformoutput
    15  
    16  import (
    17  	"io/ioutil"
    18  	"log"
    19  	"os"
    20  	"strings"
    21  
    22  	"github.com/GoogleCloudPlatform/terraformer/terraformutils"
    23  	"github.com/GoogleCloudPlatform/terraformer/terraformutils/providerwrapper"
    24  
    25  	"github.com/hashicorp/terraform/terraform"
    26  )
    27  
    28  func OutputHclFiles(resources []terraformutils.Resource, provider terraformutils.ProviderGenerator, path string, serviceName string, isCompact bool, output string) error {
    29  	if err := os.MkdirAll(path, os.ModePerm); err != nil {
    30  		return err
    31  	}
    32  	// create provider file
    33  	providerData := provider.GetProviderData()
    34  	providerData["terraform"] = map[string]interface{}{
    35  		"required_providers": []map[string]interface{}{{
    36  			provider.GetName(): map[string]interface{}{
    37  				"version": providerwrapper.GetProviderVersion(provider.GetName()),
    38  			},
    39  		}},
    40  	}
    41  
    42  	providerDataFile, err := terraformutils.Print(providerData, map[string]struct{}{}, output)
    43  	if err != nil {
    44  		return err
    45  	}
    46  	PrintFile(path+"/provider."+GetFileExtension(output), providerDataFile)
    47  
    48  	// create outputs files
    49  	outputs := map[string]interface{}{}
    50  	outputsByResource := map[string]map[string]interface{}{}
    51  
    52  	for i, r := range resources {
    53  		outputState := map[string]*terraform.OutputState{}
    54  		outputsByResource[r.InstanceInfo.Type+"_"+r.ResourceName+"_"+r.GetIDKey()] = map[string]interface{}{
    55  			"value": "${" + r.InstanceInfo.Type + "." + r.ResourceName + "." + r.GetIDKey() + "}",
    56  		}
    57  		outputState[r.InstanceInfo.Type+"_"+r.ResourceName+"_"+r.GetIDKey()] = &terraform.OutputState{
    58  			Type:  "string",
    59  			Value: r.InstanceState.Attributes[r.GetIDKey()],
    60  		}
    61  		for _, v := range provider.GetResourceConnections() {
    62  			for k, ids := range v {
    63  				if (serviceName != "" && k == serviceName) || (serviceName == "" && k == r.ServiceName()) {
    64  					if _, exist := r.InstanceState.Attributes[ids[1]]; exist {
    65  						key := ids[1]
    66  						if ids[1] == "self_link" || ids[1] == "id" {
    67  							key = r.GetIDKey()
    68  						}
    69  						linkKey := r.InstanceInfo.Type + "_" + r.ResourceName + "_" + key
    70  						outputsByResource[linkKey] = map[string]interface{}{
    71  							"value": "${" + r.InstanceInfo.Type + "." + r.ResourceName + "." + key + "}",
    72  						}
    73  						outputState[linkKey] = &terraform.OutputState{
    74  							Type:  "string",
    75  							Value: r.InstanceState.Attributes[ids[1]],
    76  						}
    77  					}
    78  				}
    79  			}
    80  		}
    81  		resources[i].Outputs = outputState
    82  	}
    83  	if len(outputsByResource) > 0 {
    84  		outputs["output"] = outputsByResource
    85  		outputsFile, err := terraformutils.Print(outputs, map[string]struct{}{}, output)
    86  		if err != nil {
    87  			return err
    88  		}
    89  		PrintFile(path+"/outputs."+GetFileExtension(output), outputsFile)
    90  	}
    91  
    92  	// group by resource by type
    93  	typeOfServices := map[string][]terraformutils.Resource{}
    94  	for _, r := range resources {
    95  		typeOfServices[r.InstanceInfo.Type] = append(typeOfServices[r.InstanceInfo.Type], r)
    96  	}
    97  	if isCompact {
    98  		err := printFile(resources, "resources", path, output)
    99  		if err != nil {
   100  			return err
   101  		}
   102  	} else {
   103  		for k, v := range typeOfServices {
   104  			fileName := strings.ReplaceAll(k, strings.Split(k, "_")[0]+"_", "")
   105  			err := printFile(v, fileName, path, output)
   106  			if err != nil {
   107  				return err
   108  			}
   109  		}
   110  	}
   111  	return nil
   112  }
   113  
   114  func printFile(v []terraformutils.Resource, fileName, path, output string) error {
   115  	for _, res := range v {
   116  		if res.DataFiles == nil {
   117  			continue
   118  		}
   119  		for fileName, content := range res.DataFiles {
   120  			if err := os.MkdirAll(path+"/data/", os.ModePerm); err != nil {
   121  				return err
   122  			}
   123  			err := ioutil.WriteFile(path+"/data/"+fileName, content, os.ModePerm)
   124  			if err != nil {
   125  				return err
   126  			}
   127  		}
   128  	}
   129  
   130  	tfFile, err := terraformutils.HclPrintResource(v, map[string]interface{}{}, output)
   131  	if err != nil {
   132  		return err
   133  	}
   134  	err = ioutil.WriteFile(path+"/"+fileName+"."+GetFileExtension(output), tfFile, os.ModePerm)
   135  	if err != nil {
   136  		return err
   137  	}
   138  
   139  	return nil
   140  }
   141  
   142  func PrintFile(path string, data []byte) {
   143  	err := ioutil.WriteFile(path, data, os.ModePerm)
   144  	if err != nil {
   145  		log.Fatal(err)
   146  		return
   147  	}
   148  }
   149  
   150  func GetFileExtension(outputFormat string) string {
   151  	if outputFormat == "json" {
   152  		return "tf.json"
   153  	}
   154  	return "tf"
   155  }