github.com/andresvia/terraform@v0.6.15-0.20160412045437-d51c75946785/builtin/providers/google/provider.go (about)

     1  package google
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  
     7  	"github.com/hashicorp/terraform/helper/pathorcontents"
     8  	"github.com/hashicorp/terraform/helper/schema"
     9  	"github.com/hashicorp/terraform/terraform"
    10  )
    11  
    12  // Provider returns a terraform.ResourceProvider.
    13  func Provider() terraform.ResourceProvider {
    14  	return &schema.Provider{
    15  		Schema: map[string]*schema.Schema{
    16  			"account_file": &schema.Schema{
    17  				Type:         schema.TypeString,
    18  				Optional:     true,
    19  				DefaultFunc:  schema.EnvDefaultFunc("GOOGLE_ACCOUNT_FILE", nil),
    20  				ValidateFunc: validateAccountFile,
    21  				Deprecated:   "Use the credentials field instead",
    22  			},
    23  
    24  			"credentials": &schema.Schema{
    25  				Type:     schema.TypeString,
    26  				Optional: true,
    27  				DefaultFunc: schema.MultiEnvDefaultFunc([]string{
    28  					"GOOGLE_CREDENTIALS",
    29  					"GOOGLE_CLOUD_KEYFILE_JSON",
    30  					"GCLOUD_KEYFILE_JSON",
    31  				}, nil),
    32  				ValidateFunc: validateCredentials,
    33  			},
    34  
    35  			"project": &schema.Schema{
    36  				Type:     schema.TypeString,
    37  				Optional: true,
    38  				DefaultFunc: schema.MultiEnvDefaultFunc([]string{
    39  					"GOOGLE_PROJECT",
    40  					"GCLOUD_PROJECT",
    41  					"CLOUDSDK_CORE_PROJECT",
    42  				}, nil),
    43  			},
    44  
    45  			"region": &schema.Schema{
    46  				Type:     schema.TypeString,
    47  				Required: true,
    48  				DefaultFunc: schema.MultiEnvDefaultFunc([]string{
    49  					"GOOGLE_REGION",
    50  					"GCLOUD_REGION",
    51  					"CLOUDSDK_COMPUTE_REGION",
    52  				}, nil),
    53  			},
    54  		},
    55  
    56  		ResourcesMap: map[string]*schema.Resource{
    57  			"google_compute_autoscaler":             resourceComputeAutoscaler(),
    58  			"google_compute_address":                resourceComputeAddress(),
    59  			"google_compute_backend_service":        resourceComputeBackendService(),
    60  			"google_compute_disk":                   resourceComputeDisk(),
    61  			"google_compute_firewall":               resourceComputeFirewall(),
    62  			"google_compute_forwarding_rule":        resourceComputeForwardingRule(),
    63  			"google_compute_global_address":         resourceComputeGlobalAddress(),
    64  			"google_compute_global_forwarding_rule": resourceComputeGlobalForwardingRule(),
    65  			"google_compute_http_health_check":      resourceComputeHttpHealthCheck(),
    66  			"google_compute_https_health_check":     resourceComputeHttpsHealthCheck(),
    67  			"google_compute_instance":               resourceComputeInstance(),
    68  			"google_compute_instance_group":         resourceComputeInstanceGroup(),
    69  			"google_compute_instance_group_manager": resourceComputeInstanceGroupManager(),
    70  			"google_compute_instance_template":      resourceComputeInstanceTemplate(),
    71  			"google_compute_network":                resourceComputeNetwork(),
    72  			"google_compute_project_metadata":       resourceComputeProjectMetadata(),
    73  			"google_compute_route":                  resourceComputeRoute(),
    74  			"google_compute_ssl_certificate":        resourceComputeSslCertificate(),
    75  			"google_compute_subnetwork":             resourceComputeSubnetwork(),
    76  			"google_compute_target_http_proxy":      resourceComputeTargetHttpProxy(),
    77  			"google_compute_target_https_proxy":     resourceComputeTargetHttpsProxy(),
    78  			"google_compute_target_pool":            resourceComputeTargetPool(),
    79  			"google_compute_url_map":                resourceComputeUrlMap(),
    80  			"google_compute_vpn_gateway":            resourceComputeVpnGateway(),
    81  			"google_compute_vpn_tunnel":             resourceComputeVpnTunnel(),
    82  			"google_container_cluster":              resourceContainerCluster(),
    83  			"google_dns_managed_zone":               resourceDnsManagedZone(),
    84  			"google_dns_record_set":                 resourceDnsRecordSet(),
    85  			"google_sql_database":                   resourceSqlDatabase(),
    86  			"google_sql_database_instance":          resourceSqlDatabaseInstance(),
    87  			"google_sql_user":                       resourceSqlUser(),
    88  			"google_pubsub_topic":                   resourcePubsubTopic(),
    89  			"google_pubsub_subscription":            resourcePubsubSubscription(),
    90  			"google_storage_bucket":                 resourceStorageBucket(),
    91  			"google_storage_bucket_acl":             resourceStorageBucketAcl(),
    92  			"google_storage_bucket_object":          resourceStorageBucketObject(),
    93  			"google_storage_object_acl":             resourceStorageObjectAcl(),
    94  		},
    95  
    96  		ConfigureFunc: providerConfigure,
    97  	}
    98  }
    99  
   100  func providerConfigure(d *schema.ResourceData) (interface{}, error) {
   101  	credentials := d.Get("credentials").(string)
   102  	if credentials == "" {
   103  		credentials = d.Get("account_file").(string)
   104  	}
   105  	config := Config{
   106  		Credentials: credentials,
   107  		Project:     d.Get("project").(string),
   108  		Region:      d.Get("region").(string),
   109  	}
   110  
   111  	if err := config.loadAndValidate(); err != nil {
   112  		return nil, err
   113  	}
   114  
   115  	return &config, nil
   116  }
   117  
   118  func validateAccountFile(v interface{}, k string) (warnings []string, errors []error) {
   119  	if v == nil {
   120  		return
   121  	}
   122  
   123  	value := v.(string)
   124  
   125  	if value == "" {
   126  		return
   127  	}
   128  
   129  	contents, wasPath, err := pathorcontents.Read(value)
   130  	if err != nil {
   131  		errors = append(errors, fmt.Errorf("Error loading Account File: %s", err))
   132  	}
   133  	if wasPath {
   134  		warnings = append(warnings, `account_file was provided as a path instead of
   135  as file contents. This support will be removed in the future. Please update
   136  your configuration to use ${file("filename.json")} instead.`)
   137  	}
   138  
   139  	var account accountFile
   140  	if err := json.Unmarshal([]byte(contents), &account); err != nil {
   141  		errors = append(errors,
   142  			fmt.Errorf("account_file not valid JSON '%s': %s", contents, err))
   143  	}
   144  
   145  	return
   146  }
   147  
   148  func validateCredentials(v interface{}, k string) (warnings []string, errors []error) {
   149  	if v == nil || v.(string) == "" {
   150  		return
   151  	}
   152  	creds := v.(string)
   153  	var account accountFile
   154  	if err := json.Unmarshal([]byte(creds), &account); err != nil {
   155  		errors = append(errors,
   156  			fmt.Errorf("credentials are not valid JSON '%s': %s", creds, err))
   157  	}
   158  
   159  	return
   160  }
   161  
   162  // getRegionFromZone returns the region from a zone for Google cloud.
   163  func getRegionFromZone(zone string) string {
   164  	if zone != "" && len(zone) > 2 {
   165  		region := zone[:len(zone)-2]
   166  		return region
   167  	}
   168  	return ""
   169  }
   170  
   171  // getRegion reads the "region" field from the given resource data and falls
   172  // back to the provider's value if not given. If the provider's value is not
   173  // given, an error is returned.
   174  func getRegion(d *schema.ResourceData, config *Config) (string, error) {
   175  	res, ok := d.GetOk("region")
   176  	if !ok {
   177  		if config.Region != "" {
   178  			return config.Region, nil
   179  		}
   180  		return "", fmt.Errorf("%q: required field is not set", "region")
   181  	}
   182  	return res.(string), nil
   183  }
   184  
   185  // getProject reads the "project" field from the given resource data and falls
   186  // back to the provider's value if not given. If the provider's value is not
   187  // given, an error is returned.
   188  func getProject(d *schema.ResourceData, config *Config) (string, error) {
   189  	res, ok := d.GetOk("project")
   190  	if !ok {
   191  		if config.Project != "" {
   192  			return config.Project, nil
   193  		}
   194  		return "", fmt.Errorf("%q: required field is not set", "project")
   195  	}
   196  	return res.(string), nil
   197  }