mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-10-01 16:21:06 +00:00
Support Bigquery Views (#230)
* Support views in Terraform.BigQuery * Add tests for Table with view, and fix existing Table test * Remove dead code * run gofmt * Address comments * Address review comments and add support for use_legacy_sql * Force transmission/storage of UseLegacySQL * Trying to fix tests * add tests for useLegacySQL
This commit is contained in:
parent
6715d0d363
commit
d23e9c668f
@ -229,7 +229,6 @@ func resourceBigQueryDatasetRead(d *schema.ResourceData, meta interface{}) error
|
||||
|
||||
d.Set("etag", res.Etag)
|
||||
d.Set("labels", res.Labels)
|
||||
d.Set("location", res.Location)
|
||||
d.Set("self_link", res.SelfLink)
|
||||
d.Set("description", res.Description)
|
||||
d.Set("friendly_name", res.FriendlyName)
|
||||
@ -238,6 +237,15 @@ func resourceBigQueryDatasetRead(d *schema.ResourceData, meta interface{}) error
|
||||
d.Set("dataset_id", res.DatasetReference.DatasetId)
|
||||
d.Set("default_table_expiration_ms", res.DefaultTableExpirationMs)
|
||||
|
||||
// Older Tables in BigQuery have no Location set in the API response. This may be an issue when importing
|
||||
// tables created before BigQuery was available in multiple zones. We can safely assume that these tables
|
||||
// are in the US, as this was the default at the time.
|
||||
if res.Location == "" {
|
||||
d.Set("location", "US")
|
||||
} else {
|
||||
d.Set("location", res.Location)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -92,6 +92,31 @@ func resourceBigQueryTable() *schema.Resource {
|
||||
},
|
||||
},
|
||||
|
||||
// View: [Optional] If specified, configures this table as a view.
|
||||
"view": &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
MaxItems: 1,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
// Query: [Required] A query that BigQuery executes when the view is
|
||||
// referenced.
|
||||
"query": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
// UseLegacySQL: [Optional] Specifies whether to use BigQuery's
|
||||
// legacy SQL for this view. The default value is true. If set to
|
||||
// false, the view will use BigQuery's standard SQL:
|
||||
"use_legacy_sql": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// TimePartitioning: [Experimental] If specified, configures time-based
|
||||
// partitioning for this table.
|
||||
"time_partitioning": &schema.Schema{
|
||||
@ -202,6 +227,10 @@ func resourceTable(d *schema.ResourceData, meta interface{}) (*bigquery.Table, e
|
||||
},
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("view"); ok {
|
||||
table.View = expandView(v)
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("description"); ok {
|
||||
table.Description = v.(string)
|
||||
}
|
||||
@ -317,6 +346,11 @@ func resourceBigQueryTableRead(d *schema.ResourceData, meta interface{}) error {
|
||||
d.Set("schema", schema)
|
||||
}
|
||||
|
||||
if res.View != nil {
|
||||
view := flattenView(res.View)
|
||||
d.Set("view", view)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -394,3 +428,22 @@ func flattenTimePartitioning(tp *bigquery.TimePartitioning) []map[string]interfa
|
||||
|
||||
return []map[string]interface{}{result}
|
||||
}
|
||||
|
||||
func expandView(configured interface{}) *bigquery.ViewDefinition {
|
||||
raw := configured.([]interface{})[0].(map[string]interface{})
|
||||
vd := &bigquery.ViewDefinition{Query: raw["query"].(string)}
|
||||
|
||||
if v, ok := raw["use_legacy_sql"]; ok {
|
||||
vd.UseLegacySql = v.(bool)
|
||||
vd.ForceSendFields = append(vd.ForceSendFields, "UseLegacySql")
|
||||
}
|
||||
|
||||
return vd
|
||||
}
|
||||
|
||||
func flattenView(vd *bigquery.ViewDefinition) []map[string]interface{} {
|
||||
result := map[string]interface{}{"query": vd.Query}
|
||||
result["use_legacy_sql"] = vd.UseLegacySql
|
||||
|
||||
return []map[string]interface{}{result}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/acctest"
|
||||
@ -37,6 +38,53 @@ func TestAccBigQueryTable_Basic(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccBigQueryTable_View(t *testing.T) {
|
||||
datasetID := fmt.Sprintf("tf_test_%s", acctest.RandString(10))
|
||||
tableID := fmt.Sprintf("tf_test_%s", acctest.RandString(10))
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckBigQueryTableDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccBigQueryTableWithView(datasetID, tableID),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccBigQueryTableExistsWithView(
|
||||
"google_bigquery_table.test"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccBigQueryTable_ViewWithLegacySQL(t *testing.T) {
|
||||
datasetID := fmt.Sprintf("tf_test_%s", acctest.RandString(10))
|
||||
tableID := fmt.Sprintf("tf_test_%s", acctest.RandString(10))
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckBigQueryTableDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccBigQueryTableWithView(datasetID, tableID),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccBigQueryTableExistsWithLegacySql(
|
||||
"google_bigquery_table.test", true),
|
||||
),
|
||||
},
|
||||
{
|
||||
Config: testAccBigQueryTableWithNewSqlView(datasetID, tableID),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccBigQueryTableExistsWithLegacySql(
|
||||
"google_bigquery_table.test", false),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckBigQueryTableDestroy(s *terraform.State) error {
|
||||
for _, rs := range s.RootModule().Resources {
|
||||
if rs.Type != "google_bigquery_table" {
|
||||
@ -44,7 +92,7 @@ func testAccCheckBigQueryTableDestroy(s *terraform.State) error {
|
||||
}
|
||||
|
||||
config := testAccProvider.Meta().(*Config)
|
||||
_, err := config.clientBigQuery.Tables.Get(config.Project, rs.Primary.Attributes["dataset_id"], rs.Primary.Attributes["name"]).Do()
|
||||
_, err := config.clientBigQuery.Tables.Get(config.Project, rs.Primary.Attributes["dataset_id"], rs.Primary.Attributes["table_id"]).Do()
|
||||
if err == nil {
|
||||
return fmt.Errorf("Table still present")
|
||||
}
|
||||
@ -64,11 +112,69 @@ func testAccBigQueryTableExists(n string) resource.TestCheckFunc {
|
||||
return fmt.Errorf("No ID is set")
|
||||
}
|
||||
config := testAccProvider.Meta().(*Config)
|
||||
_, err := config.clientBigQuery.Tables.Get(config.Project, rs.Primary.Attributes["dataset_id"], rs.Primary.Attributes["name"]).Do()
|
||||
table, err := config.clientBigQuery.Tables.Get(config.Project, rs.Primary.Attributes["dataset_id"], rs.Primary.Attributes["table_id"]).Do()
|
||||
if err != nil {
|
||||
return fmt.Errorf("BigQuery Table not present")
|
||||
}
|
||||
|
||||
if !strings.HasSuffix(table.Id, rs.Primary.Attributes["table_id"]) {
|
||||
return fmt.Errorf("BigQuery Table ID does not match expected value")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccBigQueryTableExistsWithView(n string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, ok := s.RootModule().Resources[n]
|
||||
if !ok {
|
||||
return fmt.Errorf("Not found: %s", n)
|
||||
}
|
||||
|
||||
if rs.Primary.ID == "" {
|
||||
return fmt.Errorf("No ID is set")
|
||||
}
|
||||
config := testAccProvider.Meta().(*Config)
|
||||
|
||||
table, err := config.clientBigQuery.Tables.Get(config.Project, rs.Primary.Attributes["dataset_id"], rs.Primary.Attributes["table_id"]).Do()
|
||||
if err != nil {
|
||||
return fmt.Errorf("BigQuery Table not present")
|
||||
}
|
||||
|
||||
if table.View == nil {
|
||||
return fmt.Errorf("View object missing on table")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccBigQueryTableExistsWithLegacySql(n string, useLegacySql bool) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, ok := s.RootModule().Resources[n]
|
||||
if !ok {
|
||||
return fmt.Errorf("Not found: %s", n)
|
||||
}
|
||||
|
||||
if rs.Primary.ID == "" {
|
||||
return fmt.Errorf("No ID is set")
|
||||
}
|
||||
config := testAccProvider.Meta().(*Config)
|
||||
|
||||
table, err := config.clientBigQuery.Tables.Get(config.Project, rs.Primary.Attributes["dataset_id"], rs.Primary.Attributes["table_id"]).Do()
|
||||
if err != nil {
|
||||
return fmt.Errorf("BigQuery Table not present")
|
||||
}
|
||||
|
||||
if table.View == nil {
|
||||
return fmt.Errorf("View object missing on table")
|
||||
}
|
||||
|
||||
if table.View.UseLegacySql != useLegacySql {
|
||||
return fmt.Errorf("Value of UseLegacySQL does not match expected value")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -114,6 +220,48 @@ EOH
|
||||
}`, datasetID, tableID)
|
||||
}
|
||||
|
||||
func testAccBigQueryTableWithView(datasetID, tableID string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "google_bigquery_dataset" "test" {
|
||||
dataset_id = "%s"
|
||||
}
|
||||
|
||||
resource "google_bigquery_table" "test" {
|
||||
table_id = "%s"
|
||||
dataset_id = "${google_bigquery_dataset.test.dataset_id}"
|
||||
|
||||
time_partitioning {
|
||||
type = "DAY"
|
||||
}
|
||||
|
||||
view {
|
||||
query = "SELECT state FROM [lookerdata:cdc.project_tycho_reports]"
|
||||
use_legacy_sql = true
|
||||
}
|
||||
}`, datasetID, tableID)
|
||||
}
|
||||
|
||||
func testAccBigQueryTableWithNewSqlView(datasetID, tableID string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "google_bigquery_dataset" "test" {
|
||||
dataset_id = "%s"
|
||||
}
|
||||
|
||||
resource "google_bigquery_table" "test" {
|
||||
table_id = "%s"
|
||||
dataset_id = "${google_bigquery_dataset.test.dataset_id}"
|
||||
|
||||
time_partitioning {
|
||||
type = "DAY"
|
||||
}
|
||||
|
||||
view {
|
||||
query = "%s"
|
||||
use_legacy_sql = false
|
||||
}
|
||||
}`, datasetID, tableID, "SELECT state FROM `lookerdata:cdc.project_tycho_reports`")
|
||||
}
|
||||
|
||||
func testAccBigQueryTableUpdated(datasetID, tableID string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "google_bigquery_dataset" "test" {
|
||||
|
Loading…
Reference in New Issue
Block a user