Skip to content

Commit 256429c

Browse files
kautikdkDawid212
authored andcommitted
Add storage_control_folder_intelligence_config resource. (GoogleCloudPlatform#13394)
1 parent 12de912 commit 256429c

9 files changed

+632
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
# Copyright 2025 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+
# API resource name
16+
name: 'FolderIntelligenceConfig'
17+
kind: 'storagecontrol#intelligenceconfig'
18+
# Resource description for the provider documentation.
19+
description: |
20+
The Folder Storage Intelligence resource represents GCS Storage Intelligence operating on individual GCP Folder. Storage Intelligence is a singleton resource and individual instance exists on each GCP Folder.
21+
22+
Storage Intelligence is for Storage Admins to manage GCP storage assets at scale for performance, cost, security & compliance.
23+
24+
docs:
25+
warning: |
26+
Storage Intelligence Config is a singleton resource which cannot be created or deleted. A single instance of Storage Intelligence Config exist for each GCP Folder. Terraform does not create or destroy this resource.
27+
Terraform resource creation for this resource is simply an update operation on existing resource with specified properties, absense of any optional field in the create operation will result in clearance of that field. Terraform deletion won't have any effect on this resource rather it will only remove it from the state file.
28+
29+
# URL for the resource's standard Get method. https://google.aip.dev/131
30+
self_link: 'folders/{{name}}/locations/global/intelligenceConfig'
31+
32+
custom_code:
33+
pre_create: templates/terraform/pre_create/storage_control_intelligence_config.go.tmpl
34+
35+
create_verb: 'PATCH'
36+
# The HTTP verb used to update a resource. Allowed values: :POST, :PUT, :PATCH. Default: :PUT.
37+
update_verb: 'PATCH'
38+
# If true, the resource sets an `updateMask` query parameter listing modified
39+
# fields when updating the resource. If false, it does not.
40+
update_mask: true
41+
42+
exclude_delete: true
43+
44+
import_format:
45+
- 'folders/{{name}}/locations/global/intelligenceConfig'
46+
47+
# If true, code for handling long-running operations is generated along with
48+
# the resource. If false, that code is not generated.
49+
autogen_async: false
50+
51+
examples:
52+
- name: storage_control_folder_intelligence_config_basic
53+
primary_resource_id: example
54+
vars:
55+
folder_id: "12345678"
56+
exclude_test: true
57+
exclude_import_test: true
58+
59+
properties:
60+
# Fields go here
61+
- name: 'name'
62+
type: String
63+
required: true
64+
immutable: true
65+
url_param_only: true
66+
description: |
67+
Identifier of the GCP Folder. For GCP Folder, this field can be folder number.
68+
- name: 'editionConfig'
69+
type: String
70+
required: false
71+
default_from_api: true
72+
description: |
73+
Edition configuration of the Storage Intelligence resource. Valid values are INHERIT, TRIAL, DISABLED and STANDARD.
74+
- name: 'updateTime'
75+
type: String
76+
output: true
77+
description: |
78+
The time at which the Storage Intelligence Config resource is last updated.
79+
- name: 'filter'
80+
type: NestedObject
81+
diff_suppress_func: 'intelligenceFilterDiffSuppress'
82+
description: |
83+
Filter over location and bucket using include or exclude semantics. Resources that match the include or exclude filter are exclusively included or excluded from the Storage Intelligence plan.
84+
properties:
85+
- name: excludedCloudStorageBuckets
86+
type: NestedObject
87+
required: false
88+
description: |
89+
Buckets to exclude from the Storage Intelligence plan.
90+
conflicts:
91+
- 'filter.0.included_cloud_storage_buckets'
92+
at_least_one_of:
93+
- 'filter.0.included_cloud_storage_buckets'
94+
- 'filter.0.excluded_cloud_storage_buckets'
95+
- 'filter.0.included_cloud_storage_locations'
96+
- 'filter.0.excluded_cloud_storage_locations'
97+
diff_suppress_func: 'intelligenceFilterExcludedCloudStorageBucketsDiffSuppress'
98+
properties:
99+
- name: bucketIdRegexes
100+
required: true
101+
type: Array
102+
send_empty_value: true
103+
item_type:
104+
type: String
105+
description: |
106+
List of bucket id regexes to exclude in the storage intelligence plan.
107+
- name: includedCloudStorageBuckets
108+
type: NestedObject
109+
required: false
110+
description: |
111+
Buckets to include in the Storage Intelligence plan.
112+
conflicts:
113+
- 'filter.0.excluded_cloud_storage_buckets'
114+
at_least_one_of:
115+
- 'filter.0.included_cloud_storage_buckets'
116+
- 'filter.0.excluded_cloud_storage_buckets'
117+
- 'filter.0.included_cloud_storage_locations'
118+
- 'filter.0.excluded_cloud_storage_locations'
119+
diff_suppress_func: 'intelligenceFilterincludedCloudStorageBucketsDiffSuppress'
120+
properties:
121+
- name: bucketIdRegexes
122+
required: true
123+
send_empty_value: true
124+
type: Array
125+
item_type:
126+
type: String
127+
description: |
128+
List of bucket id regexes to exclude in the storage intelligence plan.
129+
- name: excludedCloudStorageLocations
130+
type: NestedObject
131+
required: false
132+
description: |
133+
Locations to exclude from the Storage Intelligence plan.
134+
conflicts:
135+
- 'filter.0.included_cloud_storage_locations'
136+
at_least_one_of:
137+
- 'filter.0.included_cloud_storage_buckets'
138+
- 'filter.0.excluded_cloud_storage_buckets'
139+
- 'filter.0.included_cloud_storage_locations'
140+
- 'filter.0.excluded_cloud_storage_locations'
141+
diff_suppress_func: 'intelligenceFilterExcludedCloudStorageLocationsDiffSuppress'
142+
properties:
143+
- name: locations
144+
type: Array
145+
required: true
146+
send_empty_value: true
147+
description: |
148+
List of locations.
149+
item_type:
150+
type: String
151+
- name: includedCloudStorageLocations
152+
type: NestedObject
153+
required: false
154+
description: |
155+
Locations to include in the Storage Intelligence plan.
156+
conflicts:
157+
- 'filter.0.excluded_cloud_storage_locations'
158+
at_least_one_of:
159+
- 'filter.0.included_cloud_storage_buckets'
160+
- 'filter.0.excluded_cloud_storage_buckets'
161+
- 'filter.0.included_cloud_storage_locations'
162+
- 'filter.0.excluded_cloud_storage_locations'
163+
diff_suppress_func: 'intelligenceFilterincludedCloudStorageLocationsDiffSuppress'
164+
properties:
165+
- name: locations
166+
type: Array
167+
required: true
168+
send_empty_value: true
169+
description: |
170+
List of locations.
171+
item_type:
172+
type: String
173+
- name: 'effectiveIntelligenceConfig'
174+
output: true
175+
description: |
176+
The Intelligence config that is effective for the resource.
177+
type: NestedObject
178+
properties:
179+
- name: intelligenceConfig
180+
type: String
181+
output: true
182+
description: |
183+
The Intelligence config resource that is applied for the target resource.
184+
- name: effectiveEdition
185+
type: String
186+
output: true
187+
description: |
188+
The `StorageIntelligence` edition that is applicable for the resource.

mmv1/products/storagecontrol/ProjectIntelligenceConfig.yaml

+9-1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,14 @@ import_format:
4848
# the resource. If false, that code is not generated.
4949
autogen_async: false
5050

51+
examples:
52+
- name: storage_control_project_intelligence_config_basic
53+
primary_resource_id: example
54+
vars:
55+
project_id: "test-project"
56+
exclude_test: true
57+
exclude_import_test: true
58+
5159
properties:
5260
- name: 'name'
5361
type: String
@@ -61,7 +69,7 @@ properties:
6169
required: false
6270
default_from_api: true
6371
description: |
64-
Edition configuration of the Storage Intelligence resource. Valid values are INHERIT, DISABLED and STANDARD.
72+
Edition configuration of the Storage Intelligence resource. Valid values are INHERIT, TRIAL, DISABLED and STANDARD.
6573
- name: 'updateTime'
6674
type: String
6775
output: true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
resource "google_storage_control_folder_intelligence_config" "{{$.PrimaryResourceId}}" {
2+
name = "{{index $.Vars "folder_id"}}"
3+
edition_config = "STANDARD"
4+
filter {
5+
included_cloud_storage_buckets{
6+
bucket_id_regexes = ["test-id-1*", "test-id-2*"]
7+
}
8+
excluded_cloud_storage_locations{
9+
locations = ["test-location-1*", "test-locations-2*"]
10+
}
11+
}
12+
}
13+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
resource "google_storage_control_project_intelligence_config" "{{$.PrimaryResourceId}}" {
2+
name = "{{index $.Vars "project_id"}}"
3+
edition_config = "TRIAL"
4+
filter {
5+
included_cloud_storage_buckets{
6+
bucket_id_regexes = ["test-id-1*", "test-id-2*"]
7+
}
8+
}
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
updateMask := []string{"filter"}
2+
3+
if d.HasChange("edition_config") {
4+
updateMask = append(updateMask, "editionConfig")
5+
}
6+
// updateMask is a URL parameter but not present in the schema, so ReplaceVars
7+
// won't set it
8+
url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")})
9+
if err != nil {
10+
return err
11+
}

mmv1/third_party/terraform/provider/provider_mmv1_resources.go.tmpl

+2-1
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,8 @@ var handwrittenDatasources = map[string]*schema.Resource{
245245
"google_storage_bucket_object": storage.DataSourceGoogleStorageBucketObject(),
246246
"google_storage_bucket_objects": storage.DataSourceGoogleStorageBucketObjects(),
247247
"google_storage_bucket_object_content": storage.DataSourceGoogleStorageBucketObjectContent(),
248-
"google_storage_control_organization_intelligence_config": storagecontrol.DataSourceGoogleStorageControlOrganizationIntelligenceConfig(),
248+
"google_storage_control_folder_intelligence_config": storagecontrol.DataSourceGoogleStorageControlFolderIntelligenceConfig(),
249+
"google_storage_control_organization_intelligence_config": storagecontrol.DataSourceGoogleStorageControlOrganizationIntelligenceConfig(),
249250
"google_storage_control_project_intelligence_config": storagecontrol.DataSourceGoogleStorageControlProjectIntelligenceConfig(),
250251
"google_storage_object_signed_url": storage.DataSourceGoogleSignedUrl(),
251252
"google_storage_project_service_account": storage.DataSourceGoogleStorageProjectServiceAccount(),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package storagecontrol
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
7+
"github.com/hashicorp/terraform-provider-google/google/tpgresource"
8+
transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport"
9+
)
10+
11+
func DataSourceGoogleStorageControlFolderIntelligenceConfig() *schema.Resource {
12+
13+
dsSchema := tpgresource.DatasourceSchemaFromResourceSchema(ResourceStorageControlFolderIntelligenceConfig().Schema)
14+
tpgresource.AddRequiredFieldsToSchema(dsSchema, "name")
15+
16+
return &schema.Resource{
17+
Read: dataSourceGoogleStorageControlFolderIntelligenceConfigRead,
18+
Schema: dsSchema,
19+
}
20+
}
21+
22+
func dataSourceGoogleStorageControlFolderIntelligenceConfigRead(d *schema.ResourceData, meta interface{}) error {
23+
config := meta.(*transport_tpg.Config)
24+
25+
id, err := tpgresource.ReplaceVars(d, config, "folders/{{name}}/locations/global/intelligenceConfig")
26+
if err != nil {
27+
return fmt.Errorf("Error constructing id: %s", err)
28+
}
29+
d.SetId(id)
30+
err = resourceStorageControlFolderIntelligenceConfigRead(d, meta)
31+
if err != nil {
32+
return err
33+
}
34+
35+
if d.Id() == "" {
36+
return fmt.Errorf("%s not found", id)
37+
}
38+
39+
return nil
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
package storagecontrol_test
4+
5+
import (
6+
"testing"
7+
8+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
9+
"github.com/hashicorp/terraform-provider-google/google/acctest"
10+
"github.com/hashicorp/terraform-provider-google/google/envvar"
11+
)
12+
13+
func TestAccDataSourceGoogleStorageControlFolderIntelligenceConfig_basic(t *testing.T) {
14+
t.Parallel()
15+
16+
context := map[string]interface{}{
17+
"random_suffix": acctest.RandString(t, 10),
18+
"org_id": envvar.GetTestOrgFromEnv(t),
19+
}
20+
21+
acctest.VcrTest(t, resource.TestCase{
22+
PreCheck: func() { acctest.AccTestPreCheck(t) },
23+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
24+
ExternalProviders: map[string]resource.ExternalProvider{
25+
"time": {},
26+
},
27+
Steps: []resource.TestStep{
28+
{
29+
Config: testAccDataSourceGoogleStorageControlFolderIntelligenceConfig_basic(context),
30+
Check: resource.ComposeTestCheckFunc(
31+
acctest.CheckDataSourceStateMatchesResourceState("data.google_storage_control_folder_intelligence_config.folder_storage_intelligence", "google_storage_control_folder_intelligence_config.folder_storage_intelligence"),
32+
),
33+
},
34+
},
35+
})
36+
}
37+
38+
func testAccDataSourceGoogleStorageControlFolderIntelligenceConfig_basic(context map[string]interface{}) string {
39+
return acctest.Nprintf(`
40+
resource "google_folder" "folder" {
41+
parent = "organizations/%{org_id}"
42+
display_name = "tf-test-folder-name%{random_suffix}"
43+
deletion_protection=false
44+
}
45+
46+
resource "time_sleep" "wait_120_seconds" {
47+
depends_on = [google_folder.folder]
48+
create_duration = "120s"
49+
}
50+
51+
resource "google_storage_control_folder_intelligence_config" "folder_storage_intelligence" {
52+
name = google_folder.folder.folder_id
53+
edition_config = "STANDARD"
54+
depends_on = [time_sleep.wait_120_seconds]
55+
}
56+
57+
data "google_storage_control_folder_intelligence_config" "folder_storage_intelligence" {
58+
name = google_storage_control_folder_intelligence_config.folder_storage_intelligence.name
59+
}
60+
`, context)
61+
}

0 commit comments

Comments
 (0)