github.com/GoogleCloudPlatform/terraformer@v0.8.18/tests/datadog/helper.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"os"
     7  	"os/exec"
     8  	"regexp"
     9  	"strconv"
    10  	"strings"
    11  
    12  	datadog_terraforming "github.com/GoogleCloudPlatform/terraformer/providers/datadog"
    13  )
    14  
    15  var (
    16  	commandTerraformInit       = "terraform init"
    17  	commandTerraformPlan       = "terraform plan -detailed-exitcode"
    18  	commandTerraformDestroy    = "terraform destroy -auto-approve"
    19  	commandTerraformApply      = "terraform apply -auto-approve"
    20  	commandTerraformOutput     = "terraform output"
    21  	commandTerraformV13Upgrade = "terraform 0.13upgrade -yes ."
    22  	datadogResourcesPath       = "tests/datadog/resources/"
    23  )
    24  
    25  type DatadogConfig struct {
    26  	apiKey string
    27  	appKey string
    28  	apiURL string
    29  }
    30  
    31  type TerraformConfig struct {
    32  	target string
    33  }
    34  
    35  type Config struct {
    36  	Datadog      DatadogConfig
    37  	Terraform    TerraformConfig
    38  	logCMDOutput bool
    39  	rootPath     string
    40  	tfVersion    string
    41  }
    42  
    43  func getConfig() (*Config, error) {
    44  	logCMDOutput := false
    45  	if envVar := os.Getenv("LOG_CMD_OUTPUT"); envVar != "" {
    46  		logCMDOutputEnv, err := strconv.ParseBool(envVar)
    47  		if err != nil {
    48  			return nil, err
    49  		}
    50  		logCMDOutput = logCMDOutputEnv
    51  	}
    52  	rootPath, _ := os.Getwd()
    53  
    54  	return &Config{
    55  		Datadog: DatadogConfig{
    56  			apiKey: os.Getenv("DD_TEST_CLIENT_API_KEY"),
    57  			appKey: os.Getenv("DD_TEST_CLIENT_APP_KEY"),
    58  			apiURL: os.Getenv("DATADOG_HOST"),
    59  		},
    60  		Terraform: TerraformConfig{
    61  			target: os.Getenv("DATADOG_TERRAFORM_TARGET"),
    62  		},
    63  		logCMDOutput: logCMDOutput,
    64  		rootPath:     rootPath,
    65  		tfVersion:    os.Getenv("DATADOG_TF_VERSION"),
    66  	}, nil
    67  }
    68  
    69  func getAllServices(provider *datadog_terraforming.DatadogProvider) []string {
    70  	var services []string
    71  	for service := range provider.GetSupportedService() {
    72  		if service == "timeboard" {
    73  			continue
    74  		}
    75  		if service == "screenboard" {
    76  			continue
    77  		}
    78  		services = append(services, service)
    79  	}
    80  	return services
    81  }
    82  
    83  func initializeDatadogProvider(cfg *Config) error {
    84  	// Initialize the provider
    85  	log.Print("Initializing the Datadog provider")
    86  	if err := cmdRun(cfg, []string{commandTerraformInit}); err != nil {
    87  		return err
    88  	}
    89  	log.Print("Successfully initialized  the Datadog provider")
    90  	return nil
    91  }
    92  
    93  func createDatadogResource(cfg *Config) (*map[string][]string, error) {
    94  	// Create terraform -target flags if targets are passed
    95  	var terraformTargets []string
    96  	if v := cfg.Terraform.target; v != "" {
    97  		vArr := strings.Split(v, ":")
    98  		for _, terraformTarget := range vArr {
    99  			terraformTargetFlag := fmt.Sprintf("-target=%s", terraformTarget)
   100  			terraformTargets = append(terraformTargets, terraformTargetFlag)
   101  		}
   102  	}
   103  
   104  	// Create resources
   105  	log.Print("Creating resources")
   106  	if err := cmdRun(cfg, []string{commandTerraformApply, strings.Join(terraformTargets, " ")}); err != nil {
   107  		return nil, err
   108  	}
   109  
   110  	// Get output of created resources and parse the data into a map
   111  	output, err := terraformOutput()
   112  	if err != nil {
   113  		log.Println(err)
   114  		return nil, err
   115  	}
   116  	resources := parseTerraformOutput(string(output))
   117  	log.Printf("Created resources: \n%s", string(output))
   118  
   119  	return resources, nil
   120  }
   121  
   122  func terraformOutput() ([]byte, error) {
   123  	output, err := exec.Command("sh", "-c", commandTerraformOutput).Output()
   124  	if err != nil {
   125  		log.Println(err)
   126  		return nil, err
   127  	}
   128  	return output, nil
   129  }
   130  
   131  func terraformPlan(cfg *Config) error {
   132  	log.Print("Running terraform plan against resources")
   133  	err := cmdRun(cfg, []string{commandTerraformPlan})
   134  	if err != nil {
   135  		return err
   136  	}
   137  
   138  	log.Print("terraform plan did not generate diffs")
   139  	return nil
   140  }
   141  
   142  func destroyDatadogResources(cfg *Config) error {
   143  	// Destroy created resources in the /tests/datadog/resources directory
   144  	err := os.Chdir(cfg.rootPath + "/" + datadogResourcesPath)
   145  	if err != nil {
   146  		return err
   147  	}
   148  	log.Print("Destroying resources")
   149  	if err := cmdRun(cfg, []string{commandTerraformDestroy}); err != nil {
   150  		return err
   151  	}
   152  	_ = os.Chdir(cfg.rootPath)
   153  
   154  	return nil
   155  }
   156  
   157  func parseTerraformOutput(output string) *map[string][]string {
   158  	outputArr := strings.Split(output, "\n")
   159  	resources := map[string][]string{}
   160  	for _, resourceOutput := range outputArr {
   161  		if len(resourceOutput) > 0 {
   162  			resourceArr := strings.Split(resourceOutput, " = ")
   163  			resourceID := resourceArr[len(resourceArr)-1]
   164  			// Get resource name
   165  			re := regexp.MustCompile("_(.*?)(--|_)")
   166  			match := re.FindStringSubmatch(resourceArr[0])
   167  			resourceName := match[1]
   168  
   169  			resources[resourceName] = append(resources[resourceName], resourceID)
   170  		}
   171  	}
   172  	return &resources
   173  }
   174  
   175  func cmdRun(cfg *Config, args []string) error {
   176  	terraformAPIKeyEnvVariable := fmt.Sprintf("DATADOG_API_KEY=%s", cfg.Datadog.apiKey)
   177  	terraformAppKeyEnvVariable := fmt.Sprintf("DATADOG_APP_KEY=%s", cfg.Datadog.appKey)
   178  
   179  	cmd := exec.Command("sh", "-c", strings.Join(args, " "))
   180  	cmd.Env = os.Environ()
   181  	cmd.Env = append(cmd.Env, terraformAPIKeyEnvVariable, terraformAppKeyEnvVariable)
   182  	if cfg.logCMDOutput {
   183  		cmd.Stdout = os.Stdout
   184  		cmd.Stderr = os.Stderr
   185  	}
   186  
   187  	err := cmd.Run()
   188  	if err != nil {
   189  		log.Println(err)
   190  		return err
   191  	}
   192  	return nil
   193  }