Skip to content

Commit 82022a3

Browse files
authored
Add DataProduct resource support (GoogleCloudPlatform#16099)
1 parent 096dec9 commit 82022a3

5 files changed

Lines changed: 297 additions & 0 deletions

File tree

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# Copyright 2026 Google Inc.
2+
# Licensed under the Apache License, Version 2.0 (the "License");
3+
# you may not use this file except in compliance with the License.
4+
# You may obtain a copy of the License at
5+
#
6+
# http://www.apache.org/licenses/LICENSE-2.0
7+
#
8+
# Unless required by applicable law or agreed to in writing, software
9+
# distributed under the License is distributed on an "AS IS" BASIS,
10+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
# See the License for the specific language governing permissions and
12+
# limitations under the License.
13+
14+
---
15+
name: 'DataProduct'
16+
description: |
17+
A data product is a curated collection of data assets, packaged to address
18+
specific use cases.
19+
references:
20+
guides:
21+
'Introduction to Data Products': 'https://cloud.google.com/dataplex/docs/data-products-overview'
22+
api: 'https://cloud.google.com/dataplex/docs/reference/rest/v1/projects.locations.dataProducts'
23+
min_version: beta
24+
25+
base_url: 'projects/{{project}}/locations/{{location}}/dataProducts'
26+
self_link: 'projects/{{project}}/locations/{{location}}/dataProducts/{{data_product_id}}'
27+
create_url: 'projects/{{project}}/locations/{{location}}/dataProducts?dataProductId={{data_product_id}}'
28+
id_format: 'projects/{{project}}/locations/{{location}}/dataProducts/{{data_product_id}}'
29+
30+
update_verb: 'PATCH'
31+
update_mask: true
32+
autogen_async: true
33+
34+
timeouts:
35+
insert_minutes: 5
36+
update_minutes: 5
37+
delete_minutes: 5
38+
39+
# Added async block to wait for background creation/updates
40+
async:
41+
actions: ['create', 'update', 'delete']
42+
operation:
43+
base_url: '{{op_id}}'
44+
45+
import_format:
46+
- 'projects/{{project}}/locations/{{location}}/dataProducts/{{data_product_id}}'
47+
- '{{data_product_id}}'
48+
49+
examples:
50+
- name: 'dataplex_data_product_basic'
51+
primary_resource_id: 'example'
52+
vars:
53+
data_product_id: 'data-product-basic'
54+
test_env_vars:
55+
project_name: 'PROJECT_NAME'
56+
test_vars_overrides:
57+
data_product_id: 'fmt.Sprintf("tf-test-dp%s", acctest.RandString(t, 10))'
58+
- name: 'dataplex_data_product_full'
59+
primary_resource_id: 'example'
60+
vars:
61+
data_product_id: 'data-product-full'
62+
test_env_vars:
63+
project_name: 'PROJECT_NAME'
64+
test_vars_overrides:
65+
data_product_id: 'fmt.Sprintf("tf-test-dp%s", acctest.RandString(t, 10))'
66+
67+
parameters:
68+
- name: 'location'
69+
type: String
70+
required: true
71+
immutable: true
72+
url_param_only: true
73+
description: |
74+
The location for the data product.
75+
- name: 'data_product_id'
76+
type: String
77+
required: true
78+
immutable: true
79+
url_param_only: true
80+
api_name: 'name'
81+
custom_flatten: 'templates/terraform/custom_flatten/name_from_self_link.tmpl'
82+
description: |
83+
The ID of the data product.
84+
85+
properties:
86+
- name: 'uid'
87+
type: String
88+
output: true
89+
description: 'System generated unique ID.'
90+
- name: 'displayName'
91+
type: String
92+
required: true
93+
description: 'User-friendly display name.'
94+
- name: 'createTime'
95+
type: String
96+
output: true
97+
description: 'Creation timestamp.'
98+
- name: 'updateTime'
99+
type: String
100+
output: true
101+
description: 'Last update timestamp.'
102+
- name: 'etag'
103+
type: String
104+
output: true
105+
description: 'Checksum for concurrency control.'
106+
- name: 'labels'
107+
type: KeyValueLabels
108+
description: 'User-defined labels.'
109+
- name: 'description'
110+
type: String
111+
description: 'Description of the data product.'
112+
- name: 'ownerEmails'
113+
type: Array
114+
item_type:
115+
type: String
116+
required: true
117+
description: 'Emails of the owners.'
118+
- name: 'assetCount'
119+
type: Integer
120+
output: true
121+
description: 'Number of associated data assets.'
122+
- name: 'accessGroups'
123+
type: Map
124+
key_name: 'id'
125+
description: |
126+
Custom user defined access groups at the data product level.
127+
value_type:
128+
name: 'AccessGroup'
129+
type: NestedObject
130+
properties:
131+
- name: 'group_id'
132+
api_name: 'id'
133+
type: String
134+
required: true
135+
description: 'Unique identifier of the access group.'
136+
- name: 'displayName'
137+
type: String
138+
required: true
139+
description: 'User friendly display name.'
140+
- name: 'description'
141+
type: String
142+
description: 'Description of the access group.'
143+
- name: 'principal'
144+
type: NestedObject
145+
required: true
146+
description: 'The principal entity.'
147+
properties:
148+
- name: 'googleGroup'
149+
type: String
150+
description: 'Email of the Google Group.'

mmv1/products/dataplex/product.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,7 @@ display_name: 'Dataplex'
1717
versions:
1818
- name: 'ga'
1919
base_url: 'https://dataplex.googleapis.com/v1/'
20+
- name: 'beta'
21+
base_url: 'https://dataplex.googleapis.com/v1/'
2022
scopes:
2123
- 'https://www.googleapis.com/auth/cloud-platform'
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
resource "google_dataplex_data_product" "{{$.PrimaryResourceId}}" {
2+
project = "{{index $.TestEnvVars "project_name"}}"
3+
location = "us-central1"
4+
data_product_id = "{{index $.Vars "data_product_id"}}"
5+
display_name = "terraform data product"
6+
7+
owner_emails = ["terraform-test@google.com"]
8+
9+
access_groups {
10+
id = "analyst"
11+
group_id = "analyst"
12+
display_name = "Data Analyst"
13+
principal {
14+
google_group = "tf-test-analysts-%{random_suffix}@example.com"
15+
}
16+
}
17+
18+
provider = google-beta
19+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
resource "google_dataplex_data_product" "{{$.PrimaryResourceId}}" {
2+
project = "{{index $.TestEnvVars "project_name"}}"
3+
location = "us-central1"
4+
data_product_id = "{{index $.Vars "data_product_id"}}"
5+
display_name = "DP Full Test: Special Chars !@#$"
6+
7+
# UTF-8 verification
8+
description = "Updated with emojis 🚀 and brackets {test}"
9+
10+
owner_emails = ["terraform-test@google.com"]
11+
12+
labels = {
13+
env = "manual-test"
14+
}
15+
16+
access_groups {
17+
id = "analyst"
18+
group_id = "analyst"
19+
display_name = "Data Analyst - Updated"
20+
description = "In-place update verified"
21+
principal {
22+
google_group = "tf-test-analysts-%{random_suffix}@example.com"
23+
}
24+
}
25+
26+
access_groups {
27+
id = "scientist"
28+
group_id = "scientist"
29+
display_name = "Data Scientist"
30+
principal {
31+
google_group = "tf-test-scientists-%{random_suffix}@example.com"
32+
}
33+
}
34+
35+
provider = google-beta
36+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package dataplex_test
2+
3+
{{- if ne $.TargetVersionName "ga" }}
4+
import (
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
8+
"github.com/hashicorp/terraform-plugin-testing/plancheck"
9+
"github.com/hashicorp/terraform-provider-google/google/acctest"
10+
)
11+
12+
func TestAccDataplexDataProduct_update(t *testing.T) {
13+
t.Parallel()
14+
15+
context := map[string]interface{}{
16+
"data_product_id": "tf-test-dp-" + acctest.RandString(t, 10),
17+
}
18+
19+
acctest.VcrTest(t, resource.TestCase{
20+
PreCheck: func() { acctest.AccTestPreCheck(t) },
21+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderBetaFactories(t),
22+
Steps: []resource.TestStep{
23+
{
24+
// STEP 1: Initial Creation
25+
Config: testAccDataplexDataProduct_basic(context),
26+
},
27+
{
28+
ResourceName: "google_dataplex_data_product.example",
29+
ImportState: true,
30+
ImportStateVerify: true,
31+
ImportStateVerifyIgnore: []string{
32+
"labels",
33+
"terraform_labels",
34+
"effective_labels",
35+
},
36+
},
37+
{
38+
// STEP 2: Update fields in-place
39+
Config: testAccDataplexDataProduct_update(context),
40+
ConfigPlanChecks: resource.ConfigPlanChecks{
41+
PreApply: []plancheck.PlanCheck{
42+
plancheck.ExpectResourceAction("google_dataplex_data_product.example", plancheck.ResourceActionUpdate),
43+
},
44+
},
45+
},
46+
{
47+
ResourceName: "google_dataplex_data_product.example",
48+
ImportState: true,
49+
ImportStateVerify: true,
50+
ImportStateVerifyIgnore: []string{
51+
"labels",
52+
"terraform_labels",
53+
"effective_labels",
54+
},
55+
},
56+
},
57+
})
58+
}
59+
60+
func testAccDataplexDataProduct_basic(context map[string]interface{}) string {
61+
return acctest.Nprintf(`
62+
resource "google_dataplex_data_product" "example" {
63+
location = "us-central1"
64+
data_product_id = "%{data_product_id}"
65+
display_name = "initial display name"
66+
owner_emails = ["terraform-test@google.com"]
67+
68+
provider = google-beta
69+
}
70+
`, context)
71+
}
72+
73+
func testAccDataplexDataProduct_update(context map[string]interface{}) string {
74+
return acctest.Nprintf(`
75+
resource "google_dataplex_data_product" "example" {
76+
location = "us-central1"
77+
data_product_id = "%{data_product_id}"
78+
display_name = "updated display name"
79+
description = "updated description"
80+
owner_emails = ["updated-owner@google.com"]
81+
82+
labels = {
83+
env = "test"
84+
}
85+
86+
provider = google-beta
87+
}
88+
`, context)
89+
}
90+
{{- end }}

0 commit comments

Comments
 (0)