Skip to content

Commit

Permalink
Add BigQuery BIReservation Resource (GoogleCloudPlatform#8586)
Browse files Browse the repository at this point in the history
* Add BigQuery BIReservation Resource

* Add update test for BiReservation
  • Loading branch information
obada-ab authored and ron-gal committed Aug 17, 2023
1 parent ce58194 commit 2f5e316
Show file tree
Hide file tree
Showing 6 changed files with 388 additions and 0 deletions.
89 changes: 89 additions & 0 deletions mmv1/products/bigqueryreservation/BiReservation.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Copyright 2023 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

--- !ruby/object:Api::Resource
name: 'BiReservation'
base_url: 'projects/{{project}}/locations/{{location}}/biReservation'
self_link: 'projects/{{project}}/locations/{{location}}/biReservation'
create_verb: :PATCH
update_verb: :PATCH
update_mask: true
description: |
Represents a BI Reservation.
references: !ruby/object:Api::Resource::ReferenceLinks
guides:
'Introduction to Reservations': 'https://cloud.google.com/bigquery/docs/reservations-intro'
api: 'https://cloud.google.com/bigquery/docs/reference/reservations/rest/v1/BiReservation'
import_format:
[
'projects/{{project}}/locations/{{location}}/biReservation',
]
custom_code: !ruby/object:Provider::Terraform::CustomCode
pre_create: templates/terraform/update_mask.erb
custom_delete: templates/terraform/custom_delete/clear_bigquery_bi_reservation.go.erb
test_check_destroy: templates/terraform/custom_check_destroy/bigquery_bi_reservation.go.erb
examples:
- !ruby/object:Provider::Terraform::Examples
name: 'bigquery_reservation_bi_reservation_basic'
pull_external: true
primary_resource_id: 'reservation'
- !ruby/object:Provider::Terraform::Examples
name: 'bigquery_reservation_bi_reservation_full'
pull_external: true
skip_docs: true
primary_resource_id: 'reservation'
test_env_vars:
project: :PROJECT_NAME
parameters:
- !ruby/object:Api::Type::String
name: 'location'
required: true
immutable: true
url_param_only: true
description: |
LOCATION_DESCRIPTION
properties:
- !ruby/object:Api::Type::String
name: 'name'
output: true
description: |
The resource name of the singleton BI reservation. Reservation names have the form `projects/{projectId}/locations/{locationId}/biReservation`.
- !ruby/object:Api::Type::Time
name: 'updateTime'
output: true
description: |
The last update timestamp of a reservation.
A timestamp in RFC3339 UTC "Zulu" format, with nanosecond resolution and up to nine fractional digits. Examples: "2014-10-02T15:01:23Z" and "2014-10-02T15:01:23.045123456Z".
- !ruby/object:Api::Type::Integer
name: 'size'
description: |
Size of a reservation, in bytes.
- !ruby/object:Api::Type::Array
name: 'preferredTables'
description: |
Preferred tables to use BI capacity for.
item_type: !ruby/object:Api::Type::NestedObject
properties:
- !ruby/object:Api::Type::String
name: 'projectId'
description: |
The assigned project ID of the project.
- !ruby/object:Api::Type::String
name: 'datasetId'
description: |
The ID of the dataset in the above project.
- !ruby/object:Api::Type::String
name: 'tableId'
description: |
The ID of the table in the above dataset.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// BI reservation is a singleton resource and can't be deleted.
// We will check if the reservation info has been cleared

config := acctest.GoogleProviderConfig(t)

url, err := tpgresource.ReplaceVarsForTest(config, rs, "{{BigqueryReservationBasePath}}projects/{{project}}/locations/{{location}}/biReservation")
if err != nil {
return err
}

billingProject := ""

if config.BillingProject != "" {
billingProject = config.BillingProject
}

res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
Config: config,
Method: "GET",
Project: billingProject,
RawURL: url,
UserAgent: config.UserAgent,
})
if err != nil {
return nil
}

if _, ok := res["size"]; ok {
return fmt.Errorf("BIReservation was not cleared")
}
if _, ok := res["preferredTables"]; ok {
return fmt.Errorf("BIReservation was not cleared")
}

return nil
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
obj := make(map[string]interface{})
obj["preferredTables"] = []string{}
obj["size"] = 0

url, err := tpgresource.ReplaceVars(d, config, "{{BigqueryReservationBasePath}}projects/{{project}}/locations/{{location}}/biReservation")
if err != nil {
return err
}

log.Printf("[DEBUG] Clearing BIReservation %q: %#v", d.Id(), obj)
updateMask := []string{}

updateMask = append(updateMask, "size")
updateMask = append(updateMask, "preferredTables")

// updateMask is a URL parameter but not present in the schema, so ReplaceVars
// won't set it
url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")})
if err != nil {
return err
}

res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
Config: config,
Method: "PATCH",
RawURL: url,
UserAgent: userAgent,
Body: obj,
Timeout: d.Timeout(schema.TimeoutUpdate),
})

if err != nil {
return fmt.Errorf("Error clearing BIReservation %q: %s", d.Id(), err)
} else {
log.Printf("[DEBUG] Finished clearing BIReservation %q: %#v", d.Id(), res)
}

return nil
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
resource "google_bigquery_bi_reservation" "<%= ctx[:primary_resource_id] %>" {
location = "us-west2"
size = "3000000000"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
resource "google_bigquery_table" "foo" {
deletion_protection = false
dataset_id = google_bigquery_dataset.bar.dataset_id
table_id = "table_%{random_suffix}"
}

resource "google_bigquery_table" "foo2" {
deletion_protection = false
dataset_id = google_bigquery_dataset.bar2.dataset_id
table_id = "table2_%{random_suffix}"
}

resource "google_bigquery_dataset" "bar" {
dataset_id = "dataset_%{random_suffix}"
friendly_name = "test"
description = "This is a test description"
location = "EU"
}

resource "google_bigquery_dataset" "bar2" {
dataset_id = "dataset2_%{random_suffix}"
friendly_name = "test"
description = "This is a test description"
location = "EU"
}

resource "google_bigquery_bi_reservation" "<%= ctx[:primary_resource_id] %>" {
location = "EU"
size = "2800000000"
preferred_tables {
project_id = "<%= ctx[:test_env_vars]['project'] %>"
dataset_id = google_bigquery_dataset.bar.dataset_id
table_id = google_bigquery_table.foo.table_id
}
preferred_tables {
project_id = "<%= ctx[:test_env_vars]['project'] %>"
dataset_id = google_bigquery_dataset.bar2.dataset_id
table_id = google_bigquery_table.foo2.table_id
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
package bigqueryreservation_test

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"

"github.com/hashicorp/terraform-provider-google/google/acctest"
"github.com/hashicorp/terraform-provider-google/google/envvar"
)

func TestAccBigqueryReservationBiReservation_update(t *testing.T) {
t.Parallel()

context := map[string]interface{}{
"project": envvar.GetTestProjectFromEnv(),
"random_suffix": acctest.RandString(t, 10),
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
ExternalProviders: map[string]resource.ExternalProvider{
"random": {},
"time": {},
},
Steps: []resource.TestStep{
{
Config: testAccBigqueryReservationBiReservation_full(context),
},
{
ResourceName: "google_bigquery_bi_reservation.reservation",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"location"},
},
{
Config: testAccBigqueryReservationBiReservation_updateProperties(context),
},
{
ResourceName: "google_bigquery_bi_reservation.reservation",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"location"},
},
{
Config: testAccBigqueryReservationBiReservation_updateLocation(context),
},
{
ResourceName: "google_bigquery_bi_reservation.reservation",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"location"},
},
},
})
}

func testAccBigqueryReservationBiReservation_full(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_bigquery_table" "foo" {
deletion_protection = false
dataset_id = google_bigquery_dataset.bar.dataset_id
table_id = "table_%{random_suffix}"
}
resource "google_bigquery_table" "foo2" {
deletion_protection = false
dataset_id = google_bigquery_dataset.bar2.dataset_id
table_id = "table2_%{random_suffix}"
}
resource "google_bigquery_dataset" "bar" {
dataset_id = "dataset_%{random_suffix}"
friendly_name = "test"
description = "This is a test description"
location = "EU"
}
resource "google_bigquery_dataset" "bar2" {
dataset_id = "dataset2_%{random_suffix}"
friendly_name = "test"
description = "This is a test description"
location = "EU"
}
resource "google_bigquery_bi_reservation" "reservation" {
location = "europe-west1"
size = "2800000000"
preferred_tables {
project_id = "%{project}"
dataset_id = google_bigquery_dataset.bar.dataset_id
table_id = google_bigquery_table.foo.table_id
}
preferred_tables {
project_id = "%{project}"
dataset_id = google_bigquery_dataset.bar2.dataset_id
table_id = google_bigquery_table.foo2.table_id
}
}
`, context)
}

func testAccBigqueryReservationBiReservation_updateProperties(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_bigquery_table" "foo" {
deletion_protection = false
dataset_id = google_bigquery_dataset.bar.dataset_id
table_id = "table_%{random_suffix}"
}
resource "google_bigquery_table" "foo2" {
deletion_protection = false
dataset_id = google_bigquery_dataset.bar2.dataset_id
table_id = "table2_%{random_suffix}"
}
resource "google_bigquery_dataset" "bar" {
dataset_id = "dataset_%{random_suffix}"
friendly_name = "test"
description = "This is a test description"
location = "EU"
}
resource "google_bigquery_dataset" "bar2" {
dataset_id = "dataset2_%{random_suffix}"
friendly_name = "test"
description = "This is a test description"
location = "EU"
}
resource "google_bigquery_bi_reservation" "reservation" {
location = "europe-west1"
size = "3200000000"
preferred_tables {
project_id = "%{project}"
dataset_id = google_bigquery_dataset.bar2.dataset_id
table_id = google_bigquery_table.foo2.table_id
}
}
`, context)
}

func testAccBigqueryReservationBiReservation_updateLocation(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_bigquery_table" "foo" {
deletion_protection = false
dataset_id = google_bigquery_dataset.bar.dataset_id
table_id = "table_%{random_suffix}"
}
resource "google_bigquery_table" "foo2" {
deletion_protection = false
dataset_id = google_bigquery_dataset.bar2.dataset_id
table_id = "table2_%{random_suffix}"
}
resource "google_bigquery_dataset" "bar" {
dataset_id = "dataset_%{random_suffix}"
friendly_name = "test"
description = "This is a test description"
location = "EU"
}
resource "google_bigquery_dataset" "bar2" {
dataset_id = "dataset2_%{random_suffix}"
friendly_name = "test"
description = "This is a test description"
location = "EU"
}
resource "google_bigquery_bi_reservation" "reservation" {
location = "asia-southeast1"
size = "3200000000"
preferred_tables {
project_id = "%{project}"
dataset_id = google_bigquery_dataset.bar2.dataset_id
table_id = google_bigquery_table.foo2.table_id
}
}
`, context)
}

0 comments on commit 2f5e316

Please sign in to comment.