mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-10-04 17:51:11 +00:00
* Updates based on PR comments * Fix markdown nested list * Second round of feedback * Clarify pick one docs
This commit is contained in:
parent
aab9e9e0c2
commit
55991833f4
@ -31,3 +31,27 @@ func TestAccBigQueryDataset_importBasic(t *testing.T) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAccBigQueryDataset_importAccess(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
resourceName := "google_bigquery_dataset.access_test"
|
||||||
|
datasetID := fmt.Sprintf("tf_test_%s", acctest.RandString(10))
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckBigQueryDatasetDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccBigQueryDatasetWithTwoAccess(datasetID),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
ResourceName: resourceName,
|
||||||
|
ImportState: true,
|
||||||
|
ImportStateVerify: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -108,6 +108,63 @@ func resourceBigQueryDataset() *schema.Resource {
|
|||||||
Elem: &schema.Schema{Type: schema.TypeString},
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Access: [Optional] An array of objects that define dataset access
|
||||||
|
// for one or more entities. You can set this property when inserting
|
||||||
|
// or updating a dataset in order to control who is allowed to access
|
||||||
|
// the data.
|
||||||
|
"access": &schema.Schema{
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
// Computed because if unset, BQ adds 4 entries automatically
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"role": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ValidateFunc: validation.StringInSlice([]string{"OWNER", "WRITER", "READER"}, false),
|
||||||
|
},
|
||||||
|
"domain": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"group_by_email": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"special_group": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"user_by_email": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
"view": &schema.Schema{
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
MaxItems: 1,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"project_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"dataset_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"table_id": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
// SelfLink: [Output-only] A URL that can be used to access the resource
|
// SelfLink: [Output-only] A URL that can be used to access the resource
|
||||||
// again. You can use this URL in Get or Update requests to the
|
// again. You can use this URL in Get or Update requests to the
|
||||||
// resource.
|
// resource.
|
||||||
@ -180,6 +237,48 @@ func resourceDataset(d *schema.ResourceData, meta interface{}) (*bigquery.Datase
|
|||||||
dataset.Labels = labels
|
dataset.Labels = labels
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if v, ok := d.GetOk("access"); ok {
|
||||||
|
access := []*bigquery.DatasetAccess{}
|
||||||
|
for _, m := range v.([]interface{}) {
|
||||||
|
da := bigquery.DatasetAccess{}
|
||||||
|
accessMap := m.(map[string]interface{})
|
||||||
|
da.Role = accessMap["role"].(string)
|
||||||
|
if val, ok := accessMap["domain"]; ok {
|
||||||
|
da.Domain = val.(string)
|
||||||
|
}
|
||||||
|
if val, ok := accessMap["group_by_email"]; ok {
|
||||||
|
da.GroupByEmail = val.(string)
|
||||||
|
}
|
||||||
|
if val, ok := accessMap["special_group"]; ok {
|
||||||
|
da.SpecialGroup = val.(string)
|
||||||
|
}
|
||||||
|
if val, ok := accessMap["user_by_email"]; ok {
|
||||||
|
da.UserByEmail = val.(string)
|
||||||
|
}
|
||||||
|
if val, ok := accessMap["view"]; ok {
|
||||||
|
views := val.([]interface{})
|
||||||
|
if len(views) > 0 {
|
||||||
|
vm := views[0].(map[string]interface{})
|
||||||
|
if len(vm) > 0 {
|
||||||
|
view := bigquery.TableReference{}
|
||||||
|
if dsId, ok := vm["dataset_id"]; ok {
|
||||||
|
view.DatasetId = dsId.(string)
|
||||||
|
}
|
||||||
|
if pId, ok := vm["project_id"]; ok {
|
||||||
|
view.ProjectId = pId.(string)
|
||||||
|
}
|
||||||
|
if tId, ok := vm["table_id"]; ok {
|
||||||
|
view.TableId = tId.(string)
|
||||||
|
}
|
||||||
|
da.View = &view
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
access = append(access, &da)
|
||||||
|
}
|
||||||
|
dataset.Access = access
|
||||||
|
}
|
||||||
|
|
||||||
return dataset, nil
|
return dataset, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,6 +327,9 @@ func resourceBigQueryDatasetRead(d *schema.ResourceData, meta interface{}) error
|
|||||||
d.Set("project", id.Project)
|
d.Set("project", id.Project)
|
||||||
d.Set("etag", res.Etag)
|
d.Set("etag", res.Etag)
|
||||||
d.Set("labels", res.Labels)
|
d.Set("labels", res.Labels)
|
||||||
|
if err := d.Set("access", flattenAccess(res.Access)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
d.Set("self_link", res.SelfLink)
|
d.Set("self_link", res.SelfLink)
|
||||||
d.Set("description", res.Description)
|
d.Set("description", res.Description)
|
||||||
d.Set("friendly_name", res.FriendlyName)
|
d.Set("friendly_name", res.FriendlyName)
|
||||||
@ -304,3 +406,27 @@ func parseBigQueryDatasetId(id string) (*bigQueryDatasetId, error) {
|
|||||||
|
|
||||||
return nil, fmt.Errorf("Invalid BigQuery dataset specifier. Expecting {project}:{dataset-id}, got %s", id)
|
return nil, fmt.Errorf("Invalid BigQuery dataset specifier. Expecting {project}:{dataset-id}, got %s", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func flattenAccess(a []*bigquery.DatasetAccess) []map[string]interface{} {
|
||||||
|
access := make([]map[string]interface{}, 0, len(a))
|
||||||
|
for _, da := range a {
|
||||||
|
ai := map[string]interface{}{
|
||||||
|
"role": da.Role,
|
||||||
|
"domain": da.Domain,
|
||||||
|
"group_by_email": da.GroupByEmail,
|
||||||
|
"special_group": da.SpecialGroup,
|
||||||
|
"user_by_email": da.UserByEmail,
|
||||||
|
}
|
||||||
|
if da.View != nil {
|
||||||
|
view := []map[string]interface{}{{
|
||||||
|
"project_id": da.View.ProjectId,
|
||||||
|
"dataset_id": da.View.DatasetId,
|
||||||
|
"table_id": da.View.TableId,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
ai["view"] = view
|
||||||
|
}
|
||||||
|
access = append(access, ai)
|
||||||
|
}
|
||||||
|
return access
|
||||||
|
}
|
||||||
|
@ -38,6 +38,53 @@ func TestAccBigQueryDataset_basic(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAccBigQueryDataset_access(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
datasetID := fmt.Sprintf("tf_test_access_%s", acctest.RandString(10))
|
||||||
|
otherDatasetID := fmt.Sprintf("tf_test_other_%s", acctest.RandString(10))
|
||||||
|
otherTableID := fmt.Sprintf("tf_test_other_%s", acctest.RandString(10))
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckBigQueryDatasetDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccBigQueryDatasetWithOneAccess(datasetID),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckBigQueryDatasetExists(
|
||||||
|
"google_bigquery_dataset.access_test"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
Config: testAccBigQueryDatasetWithTwoAccess(datasetID),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckBigQueryDatasetExists(
|
||||||
|
"google_bigquery_dataset.access_test"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
Config: testAccBigQueryDatasetWithOneAccess(datasetID),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckBigQueryDatasetExists(
|
||||||
|
"google_bigquery_dataset.access_test"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
Config: testAccBigQueryDatasetWithViewAccess(datasetID, otherDatasetID, otherTableID),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckBigQueryDatasetExists(
|
||||||
|
"google_bigquery_dataset.access_test"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func testAccCheckBigQueryDatasetDestroy(s *terraform.State) error {
|
func testAccCheckBigQueryDatasetDestroy(s *terraform.State) error {
|
||||||
config := testAccProvider.Meta().(*Config)
|
config := testAccProvider.Meta().(*Config)
|
||||||
|
|
||||||
@ -112,3 +159,85 @@ resource "google_bigquery_dataset" "test" {
|
|||||||
}
|
}
|
||||||
}`, datasetID)
|
}`, datasetID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testAccBigQueryDatasetWithOneAccess(datasetID string) string {
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
resource "google_bigquery_dataset" "access_test" {
|
||||||
|
dataset_id = "%s"
|
||||||
|
|
||||||
|
access {
|
||||||
|
role = "OWNER"
|
||||||
|
user_by_email = "Joe@example.com"
|
||||||
|
}
|
||||||
|
|
||||||
|
labels {
|
||||||
|
env = "foo"
|
||||||
|
default_table_expiration_ms = 3600000
|
||||||
|
}
|
||||||
|
}`, datasetID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccBigQueryDatasetWithTwoAccess(datasetID string) string {
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
resource "google_bigquery_dataset" "access_test" {
|
||||||
|
dataset_id = "%s"
|
||||||
|
|
||||||
|
access {
|
||||||
|
role = "OWNER"
|
||||||
|
user_by_email = "Joe@example.com"
|
||||||
|
}
|
||||||
|
access {
|
||||||
|
role = "READER"
|
||||||
|
domain = "example.com"
|
||||||
|
}
|
||||||
|
|
||||||
|
labels {
|
||||||
|
env = "foo"
|
||||||
|
default_table_expiration_ms = 3600000
|
||||||
|
}
|
||||||
|
}`, datasetID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccBigQueryDatasetWithViewAccess(datasetID, otherDatasetID, otherTableID string) string {
|
||||||
|
// Note that we have to add a non-view access to prevent BQ from creating 4 default
|
||||||
|
// access entries.
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
resource "google_bigquery_dataset" "other_dataset" {
|
||||||
|
dataset_id = "%s"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_bigquery_table" "table_with_view" {
|
||||||
|
table_id = "%s"
|
||||||
|
dataset_id = "${google_bigquery_dataset.other_dataset.dataset_id}"
|
||||||
|
|
||||||
|
time_partitioning {
|
||||||
|
type = "DAY"
|
||||||
|
}
|
||||||
|
|
||||||
|
view {
|
||||||
|
query = "SELECT state FROM [lookerdata:cdc.project_tycho_reports]"
|
||||||
|
use_legacy_sql = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_bigquery_dataset" "access_test" {
|
||||||
|
dataset_id = "%s"
|
||||||
|
|
||||||
|
access {
|
||||||
|
role = "OWNER"
|
||||||
|
user_by_email = "Joe@example.com"
|
||||||
|
}
|
||||||
|
access {
|
||||||
|
view {
|
||||||
|
project_id = "${google_bigquery_dataset.other_dataset.project}"
|
||||||
|
dataset_id = "${google_bigquery_dataset.other_dataset.dataset_id}"
|
||||||
|
table_id = "${google_bigquery_table.table_with_view.table_id}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
labels {
|
||||||
|
env = "foo"
|
||||||
|
default_table_expiration_ms = 3600000
|
||||||
|
}
|
||||||
|
}`, otherDatasetID, otherTableID, datasetID)
|
||||||
|
}
|
||||||
|
@ -26,6 +26,15 @@ resource "google_bigquery_dataset" "default" {
|
|||||||
labels {
|
labels {
|
||||||
env = "default"
|
env = "default"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
access {
|
||||||
|
role = "READER"
|
||||||
|
domain = "example.com"
|
||||||
|
}
|
||||||
|
access {
|
||||||
|
role = "WRITER"
|
||||||
|
group_by_email = "writers@example.com"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -73,6 +82,43 @@ The following arguments are supported:
|
|||||||
|
|
||||||
* `labels` - (Optional) A mapping of labels to assign to the resource.
|
* `labels` - (Optional) A mapping of labels to assign to the resource.
|
||||||
|
|
||||||
|
* `access` - (Optional) An array of objects that define dataset access for
|
||||||
|
one or more entities. Structure is documented below.
|
||||||
|
|
||||||
|
The `access` block supports the following fields (exactly one of `domain`,
|
||||||
|
`group_by_email`, `special_group`, `user_by_email`, or `view` must be set,
|
||||||
|
even though they are marked optional):
|
||||||
|
* `role` - (Required unless `view` is set) Describes the rights granted to
|
||||||
|
the user specified by the other member of the access object. The following
|
||||||
|
string values are supported: `READER`, `WRITER`, `OWNER`.
|
||||||
|
|
||||||
|
* `domain` - (Optional) A domain to grant access to.
|
||||||
|
|
||||||
|
* `group_by_email` - (Optional) An email address of a Google Group to grant
|
||||||
|
access to.
|
||||||
|
|
||||||
|
* `special_group` - (Optional) A special group to grant access to.
|
||||||
|
Possible values include:
|
||||||
|
* `projectOwners`: Owners of the enclosing project.
|
||||||
|
* `projectReaders`: Readers of the enclosing project.
|
||||||
|
* `projectWriters`: Writers of the enclosing project.
|
||||||
|
* `allAuthenticatedUsers`: All authenticated BigQuery users.
|
||||||
|
|
||||||
|
* `user_by_email` - (Optional) An email address of a user to grant access to.
|
||||||
|
|
||||||
|
* `view` - (Optional) A view from a different dataset to grant access to.
|
||||||
|
Queries executed against that view will have read access to tables in this
|
||||||
|
dataset. The role field is not required when this field is set. If that
|
||||||
|
view is updated by any user, access to the view needs to be granted again
|
||||||
|
via an update operation. Structure is documented below.
|
||||||
|
|
||||||
|
The `access.view` block supports:
|
||||||
|
* `dataset_id` - (Required) The ID of the dataset containing this table.
|
||||||
|
|
||||||
|
* `project_id` - (Required) The ID of the project containing this table.
|
||||||
|
|
||||||
|
* `table_id` - (Required) The ID of the table.
|
||||||
|
|
||||||
## Attributes Reference
|
## Attributes Reference
|
||||||
|
|
||||||
In addition to the arguments listed above, the following computed attributes are
|
In addition to the arguments listed above, the following computed attributes are
|
||||||
|
Loading…
Reference in New Issue
Block a user