From c8c7d6baa3375d3c712afe4f078409e44adf4237 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 2 Jul 2014 20:47:10 -0700 Subject: [PATCH] terraform: add some semantic check functions --- terraform/semantics.go | 134 +------------------ terraform/semantics_test.go | 21 +++ terraform/test-fixtures/smc-uservars/main.tf | 8 ++ 3 files changed, 34 insertions(+), 129 deletions(-) create mode 100644 terraform/semantics_test.go create mode 100644 terraform/test-fixtures/smc-uservars/main.tf diff --git a/terraform/semantics.go b/terraform/semantics.go index adafdbaa53..0a40506fd5 100644 --- a/terraform/semantics.go +++ b/terraform/semantics.go @@ -1,147 +1,24 @@ package terraform -/* import ( "fmt" "github.com/hashicorp/terraform/config" ) -/* -// smcProviders matches up the resources with a provider and initializes -// it. This does not call "Configure" on the ResourceProvider, since that -// might actually depend on upstream resources. -func smcProviders( - c *Config) (map[*config.Resource]*terraformProvider, []error) { - var errs []error - - // Keep track of providers we know we couldn't instantiate so - // that we don't get a ton of errors about the same provider. - failures := make(map[string]struct{}) - - // Go through each resource and match it up to a provider - mapping := make(map[*config.Resource]*terraformProvider) - providers := make(map[string]ResourceProvider) - tpcache := make(map[string]*terraformProvider) - -ResourceLoop: - for _, r := range c.Config.Resources { - // Find the prefixes that match this in the order of - // longest matching first (most specific) - prefixes := matchingPrefixes(r.Type, c.Providers) - if len(prefixes) > 0 { - if _, ok := failures[prefixes[0]]; ok { - // We already failed this provider, meaning this - // resource will never succeed, so just continue. - continue - } - } - - // Go through each prefix and instantiate if necessary, then - // verify if this provider is of use to us or not. - var providerName string - var provider ResourceProvider - for _, prefix := range prefixes { - // Initialize the provider - p, ok := providers[prefix] - if !ok { - var err error - p, err = c.Providers[prefix]() - if err != nil { - errs = append(errs, fmt.Errorf( - "Error instantiating resource provider for "+ - "prefix %s: %s", prefix, err)) - - // Record the error so that we don't check it again - failures[prefix] = struct{}{} - - // Jump to the next resource - continue ResourceLoop - } - - providers[prefix] = p - } - - // Test if this provider matches what we need - if !ProviderSatisfies(p, r.Type) { - continue - } - - providerName = prefix - provider = p - break - } - - // If we didn't find a valid provider, then error and continue - if providerName == "" { - errs = append(errs, fmt.Errorf( - "Provider for resource %s not found.", - r.Id())) - continue - } - - // Find the matching provider configuration for this resource - var pc *config.ProviderConfig - pcName := config.ProviderConfigName(r.Type, c.Config.ProviderConfigs) - if pcName != "" { - pc = c.Config.ProviderConfigs[pcName] - } - - // Look up if we already have a provider for this pair of PC - // and provider name. If not, create it. - cacheKey := fmt.Sprintf("%s|%s", pcName, providerName) - tp, ok := tpcache[cacheKey] - if !ok { - renew := false - for _, tp := range tpcache { - if tp.Provider == provider { - renew = true - break - } - } - - if renew { - var err error - provider, err = c.Providers[providerName]() - if err != nil { - errs = append(errs, fmt.Errorf( - "Error instantiating resource provider for "+ - "prefix %s: %s", providerName, err)) - continue - } - } - - tp = &terraformProvider{ - Provider: provider, - Config: pc, - } - tpcache[cacheKey] = tp - } - - mapping[r] = tp - } - - if len(errs) > 0 { - return nil, errs - } - - return mapping, nil -} - -// smcVariables does all the semantic checks to verify that the -// variables given in the configuration to instantiate a Terraform -// struct are valid. -func smcVariables(c *Config) []error { +// smcUserVariables does all the semantic checks to verify that the +// variables given satisfy the configuration itself. +func smcUserVariables(c *config.Config, vs map[string]string) []error { var errs []error // Check that all required variables are present required := make(map[string]struct{}) - for k, v := range c.Config.Variables { + for k, v := range c.Variables { if v.Required() { required[k] = struct{}{} } } - for k, _ := range c.Variables { + for k, _ := range vs { delete(required, k) } if len(required) > 0 { @@ -155,4 +32,3 @@ func smcVariables(c *Config) []error { return errs } -*/ diff --git a/terraform/semantics_test.go b/terraform/semantics_test.go new file mode 100644 index 0000000000..9d7d30ebc3 --- /dev/null +++ b/terraform/semantics_test.go @@ -0,0 +1,21 @@ +package terraform + +import ( + "testing" +) + +func TestSMCUserVariables(t *testing.T) { + c := testConfig(t, "smc-uservars") + + // Required variables not set + errs := smcUserVariables(c, nil) + if len(errs) == 0 { + t.Fatal("should have errors") + } + + // Required variables set, optional variables unset + errs = smcUserVariables(c, map[string]string{"foo": "bar"}) + if len(errs) != 0 { + t.Fatalf("err: %#v", errs) + } +} diff --git a/terraform/test-fixtures/smc-uservars/main.tf b/terraform/test-fixtures/smc-uservars/main.tf new file mode 100644 index 0000000000..7e2d10c110 --- /dev/null +++ b/terraform/test-fixtures/smc-uservars/main.tf @@ -0,0 +1,8 @@ +# Required +variable "foo" { +} + +# Optional +variable "bar" { + default = "baz" +}