diff --git a/mmv1/products/biglake/Table.yaml b/mmv1/products/biglake/Table.yaml new file mode 100644 index 000000000000..c30733a322b4 --- /dev/null +++ b/mmv1/products/biglake/Table.yaml @@ -0,0 +1,134 @@ +# 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: "Table" +description: | + Represents a table. +references: !ruby/object:Api::Resource::ReferenceLinks + guides: + "Manage open source metadata with BigLake Metastore": "https://cloud.google.com/bigquery/docs/manage-open-source-metadata#create_tables" + api: "https://cloud.google.com/bigquery/docs/reference/biglake/rest/v1/projects.locations.catalogs.databases.tables" +base_url: "{{database}}/tables" +self_link: "{{database}}/tables/{{name}}" +create_url: "{{database}}/tables?tableId={{name}}" +id_format: "{{database}}/tables/{{name}}" +import_format: ["{{%database}}/tables/{{name}}"] +update_verb: :PATCH +update_mask: true +examples: + - !ruby/object:Provider::Terraform::Examples + name: "biglake_table" + primary_resource_id: "table" + vars: + name: "my_table" + catalog: "my_catalog" + database: "my_database" + bucket: "my_bucket" + +parameters: + - !ruby/object:Api::Type::String + name: "name" + required: true + immutable: true + url_param_only: true + description: | + Output only. The name of the Table. Format: + projects/{project_id_or_number}/locations/{locationId}/catalogs/{catalogId}/databases/{databaseId}/tables/{tableId} + - !ruby/object:Api::Type::String + name: "database" + immutable: true + url_param_only: true + description: | + The id of the parent database. +properties: + - !ruby/object:Api::Type::String + name: "createTime" + description: | + Output only. The creation time of the table. 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". + output: true + - !ruby/object:Api::Type::String + name: "updateTime" + description: | + Output only. The last modification time of the table. 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". + output: true + - !ruby/object:Api::Type::String + name: "deleteTime" + description: | + Output only. The deletion time of the table. Only set after the + table is deleted. 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". + output: true + - !ruby/object:Api::Type::String + name: "expireTime" + description: | + Output only. The time when this table is considered expired. Only set + after the table is deleted. 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". + output: true + - !ruby/object:Api::Type::String + name: "etag" + description: | + The checksum of a table object computed by the server based on the value + of other fields. It may be sent on update requests to ensure the client + has an up-to-date value before proceeding. It is only checked for update + table operations. + output: true + + - !ruby/object:Api::Type::Enum + name: "type" + description: | + The database type. + values: + - :HIVE + - !ruby/object:Api::Type::NestedObject + name: "hiveOptions" + description: | + Options of a Hive table. + properties: + - !ruby/object:Api::Type::KeyValuePairs + name: "parameters" + description: | + Stores user supplied Hive table parameters. An object containing a + list of "key": value pairs. + Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }. + - !ruby/object:Api::Type::String + name: "tableType" + description: | + Hive table type. For example, MANAGED_TABLE, EXTERNAL_TABLE. + - !ruby/object:Api::Type::NestedObject + name: "storageDescriptor" + description: | + Stores physical storage information on the data. + properties: + - !ruby/object:Api::Type::String + name: "locationUri" + description: | + Cloud Storage folder URI where the table data is stored, starting with "gs://". + - !ruby/object:Api::Type::String + name: "inputFormat" + description: | + The fully qualified Java class name of the input format. + - !ruby/object:Api::Type::String + name: "outputFormat" + description: | + The fully qualified Java class name of the output format. diff --git a/mmv1/templates/terraform/examples/biglake_table.tf.erb b/mmv1/templates/terraform/examples/biglake_table.tf.erb new file mode 100644 index 000000000000..e64af6fbf2b0 --- /dev/null +++ b/mmv1/templates/terraform/examples/biglake_table.tf.erb @@ -0,0 +1,61 @@ +resource "google_biglake_catalog" "catalog" { + name = "<%= ctx[:vars]['catalog'] %>" + location = "US" +} + +resource "google_storage_bucket" "bucket" { + name = "<%= ctx[:vars]['bucket'] %>" + location = "US" + force_destroy = true + uniform_bucket_level_access = true +} + +resource "google_storage_bucket_object" "metadata_folder" { + name = "metadata/" + content = " " + bucket = google_storage_bucket.bucket.name +} + + +resource "google_storage_bucket_object" "data_folder" { + name = "data/" + content = " " + bucket = google_storage_bucket.bucket.name +} + +resource "google_biglake_database" "database" { + name = "<%= ctx[:vars]['database'] %>" + catalog = google_biglake_catalog.catalog.id + type = "HIVE" + hive_options { + location_uri = "gs://${google_storage_bucket.bucket.name}/${google_storage_bucket_object.metadata_folder.name}" + parameters = { + "owner" = "Alex" + } + } +} + +resource "google_biglake_table" "<%= ctx[:primary_resource_id] %>" { + name = "<%= ctx[:vars]['name'] %>" + database = google_biglake_database.database.id + type = "HIVE" + hive_options { + table_type = "MANAGED_TABLE" + storage_descriptor { + location_uri = "gs://${google_storage_bucket.bucket.name}/${google_storage_bucket_object.data_folder.name}" + input_format = "org.apache.hadoop.mapred.SequenceFileInputFormat" + output_format = "org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat" + } + # Some Example Parameters. + parameters = { + "spark.sql.create.version" = "3.1.3" + "spark.sql.sources.schema.numParts" = "1" + "transient_lastDdlTime" = "1680894197" + "spark.sql.partitionProvider" = "catalog" + "owner" = "John Doe" + "spark.sql.sources.schema.part.0"= "{\"type\":\"struct\",\"fields\":[{\"name\":\"id\",\"type\":\"integer\",\"nullable\":true,\"metadata\":{}},{\"name\":\"name\",\"type\":\"string\",\"nullable\":true,\"metadata\":{}},{\"name\":\"age\",\"type\":\"integer\",\"nullable\":true,\"metadata\":{}}]}" + "spark.sql.sources.provider" = "iceberg" + "provider" = "iceberg" + } + } +} diff --git a/mmv1/third_party/terraform/services/biglake/resource_biglake_table_test.go b/mmv1/third_party/terraform/services/biglake/resource_biglake_table_test.go new file mode 100644 index 000000000000..a63eafb18097 --- /dev/null +++ b/mmv1/third_party/terraform/services/biglake/resource_biglake_table_test.go @@ -0,0 +1,106 @@ +package biglake_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + "github.com/hashicorp/terraform-provider-google/google/acctest" +) + +func TestAccBiglakeTable_biglakeTable_update(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckBiglakeTableDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccBiglakeTable_biglakeTableExample(context), + }, + { + ResourceName: "google_biglake_table.table", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"name", "database"}, + }, + { + Config: testAccBiglakeTable_biglakeTable_update(context), + }, + { + ResourceName: "google_biglake_table.table", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"name", "database"}, + }, + }, + }) +} + +func testAccBiglakeTable_biglakeTable_update(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_biglake_catalog" "catalog" { + name = "tf_test_my_catalog%{random_suffix}" + location = "US" +} +resource "google_storage_bucket" "bucket" { + name = "tf_test_my_bucket%{random_suffix}" + location = "US" + force_destroy = true + uniform_bucket_level_access = true +} +resource "google_storage_bucket_object" "metadata_folder" { + name = "metadata/" + content = " " + bucket = google_storage_bucket.bucket.name +} +resource "google_storage_bucket_object" "data_folder" { + name = "data/" + content = " " + bucket = google_storage_bucket.bucket.name +} +resource "google_biglake_database" "database" { + name = "tf_test_my_database%{random_suffix}" + catalog = google_biglake_catalog.catalog.id + type = "HIVE" + hive_options { + location_uri = "gs://${google_storage_bucket.bucket.name}/${google_storage_bucket_object.metadata_folder.name}" + parameters = { + "owner" = "Alex" + } + } +} +resource "google_biglake_table" "table" { + name = "tf_test_my_table%{random_suffix}" + database = google_biglake_database.database.id + type = "HIVE" + hive_options { + table_type = "EXTERNAL_TABLE" + storage_descriptor { + location_uri = "gs://${google_storage_bucket.bucket.name}/${google_storage_bucket_object.data_folder.name}/data" + input_format = "org.apache.hadoop.mapred.SequenceFileInputFormat2" + output_format = "org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat2" + } + # Some Example Parameters. + parameters = { + # Bump the version. + "spark.sql.create.version" = "3.1.7" + "spark.sql.sources.schema.numParts" = "1" + # Update the time. + "transient_lastDdlTime" = "1680895000" + "spark.sql.partitionProvider" = "catalog" + # Change The Name + "owner" = "Dana" + "spark.sql.sources.schema.part.0" = "{\"type\":\"struct\",\"fields\":[{\"name\":\"id\",\"type\":\"integer\",\"nullable\":true,\"metadata\":{}},{\"name\":\"name\",\"type\":\"string\",\"nullable\":true,\"metadata\":{}},{\"name\":\"age\",\"type\":\"integer\",\"nullable\":true,\"metadata\":{}}]}" + "spark.sql.sources.provider": "iceberg" + "provider" = "iceberg" + } + } +} +`, context) +}