Skip to content

Commit 3956203

Browse files
Terraform support for Workbench instances (#9368) (#16773)
* Workbench Instances * fix yaml to run tests * fix yaml to run tests * fix basic test * diff suppress for tags * add custom flattens * Add labels example * fix tags diff * custom_flatten with ignore_read * removed ignore_read * remove ignore_read on disks * Add kms key in full test * read_ignore for examples * clean up extra flattens * add update test * fix indent lint * fix wbi lint * fix lint issues * fix whitespace * change names in full test to vars * change tests to use variable names instead of hard coded values * stop wbi before updating machine_type * all tests passing * fix terraformgoogleconversion-codegen compiler error * make service account immutable * addressed issues with immutable fields * add disable_proxy_access into full example * Add disable_proxy_access in full test * remove returns in pre and post updates * test false values in secure vm config * fix empty shielded instance config * fixed update on non stop needing fields failing * create custom update mask * make disks sub fields completely immutable * update tests for shielded config and gpu driver * Removed scopes block from product * removed apis required * break shielded_instance_config update msk into submasks * revert update mask for shieldedInstanceConfig * Make vm image immutable * Remove gpu driver config * remove shielded instance config field * removed unspecified values in enums * reupload * removed max_items in serviceAccounts [upstream:c2f6cc6bfdc7c160de0eb36c9b9c9e6f151d8bba] Signed-off-by: Modular Magician <[email protected]>
1 parent 3de528f commit 3956203

19 files changed

+3903
-3
lines changed

.changelog/9368.txt

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
```release-note: new-resource
2+
google_workbench_instance
3+
```
4+
```release-note: new-resource
5+
google_workbench_instance_iam_*
6+
```

.teamcity/components/generated/services.kt

+5
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,11 @@ var services = mapOf(
641641
"displayName" to "Vpcaccess",
642642
"path" to "./google/services/vpcaccess"
643643
),
644+
"workbench" to mapOf(
645+
"name" to "workbench",
646+
"displayName" to "Workbench",
647+
"path" to "./google/services/workbench"
648+
),
644649
"workflows" to mapOf(
645650
"name" to "workflows",
646651
"displayName" to "Workflows",

google/fwmodels/provider_model.go

+1
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ type ProviderModel struct {
130130
VertexAICustomEndpoint types.String `tfsdk:"vertex_ai_custom_endpoint"`
131131
VmwareengineCustomEndpoint types.String `tfsdk:"vmwareengine_custom_endpoint"`
132132
VPCAccessCustomEndpoint types.String `tfsdk:"vpc_access_custom_endpoint"`
133+
WorkbenchCustomEndpoint types.String `tfsdk:"workbench_custom_endpoint"`
133134
WorkflowsCustomEndpoint types.String `tfsdk:"workflows_custom_endpoint"`
134135

135136
// Handwritten Products / Versioned / Atypical Entries

google/fwprovider/framework_provider.go

+6
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,12 @@ func (p *FrameworkProvider) Schema(_ context.Context, _ provider.SchemaRequest,
760760
transport_tpg.CustomEndpointValidator(),
761761
},
762762
},
763+
"workbench_custom_endpoint": &schema.StringAttribute{
764+
Optional: true,
765+
Validators: []validator.String{
766+
transport_tpg.CustomEndpointValidator(),
767+
},
768+
},
763769
"workflows_custom_endpoint": &schema.StringAttribute{
764770
Optional: true,
765771
Validators: []validator.String{

google/fwtransport/framework_config.go

+10
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ type FrameworkProviderConfig struct {
155155
VertexAIBasePath string
156156
VmwareengineBasePath string
157157
VPCAccessBasePath string
158+
WorkbenchBasePath string
158159
WorkflowsBasePath string
159160
}
160161

@@ -299,6 +300,7 @@ func (p *FrameworkProviderConfig) LoadAndValidateFramework(ctx context.Context,
299300
p.VertexAIBasePath = data.VertexAICustomEndpoint.ValueString()
300301
p.VmwareengineBasePath = data.VmwareengineCustomEndpoint.ValueString()
301302
p.VPCAccessBasePath = data.VPCAccessCustomEndpoint.ValueString()
303+
p.WorkbenchBasePath = data.WorkbenchCustomEndpoint.ValueString()
302304
p.WorkflowsBasePath = data.WorkflowsCustomEndpoint.ValueString()
303305

304306
p.Context = ctx
@@ -1259,6 +1261,14 @@ func (p *FrameworkProviderConfig) HandleDefaults(ctx context.Context, data *fwmo
12591261
data.VPCAccessCustomEndpoint = types.StringValue(customEndpoint.(string))
12601262
}
12611263
}
1264+
if data.WorkbenchCustomEndpoint.IsNull() {
1265+
customEndpoint := transport_tpg.MultiEnvDefault([]string{
1266+
"GOOGLE_WORKBENCH_CUSTOM_ENDPOINT",
1267+
}, transport_tpg.DefaultBasePaths[transport_tpg.WorkbenchBasePathKey])
1268+
if customEndpoint != nil {
1269+
data.WorkbenchCustomEndpoint = types.StringValue(customEndpoint.(string))
1270+
}
1271+
}
12621272
if data.WorkflowsCustomEndpoint.IsNull() {
12631273
customEndpoint := transport_tpg.MultiEnvDefault([]string{
12641274
"GOOGLE_WORKFLOWS_CUSTOM_ENDPOINT",

google/provider/provider.go

+6
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,11 @@ func Provider() *schema.Provider {
655655
Optional: true,
656656
ValidateFunc: transport_tpg.ValidateCustomEndpoint,
657657
},
658+
"workbench_custom_endpoint": {
659+
Type: schema.TypeString,
660+
Optional: true,
661+
ValidateFunc: transport_tpg.ValidateCustomEndpoint,
662+
},
658663
"workflows_custom_endpoint": {
659664
Type: schema.TypeString,
660665
Optional: true,
@@ -964,6 +969,7 @@ func ProviderConfigure(ctx context.Context, d *schema.ResourceData, p *schema.Pr
964969
config.VertexAIBasePath = d.Get("vertex_ai_custom_endpoint").(string)
965970
config.VmwareengineBasePath = d.Get("vmwareengine_custom_endpoint").(string)
966971
config.VPCAccessBasePath = d.Get("vpc_access_custom_endpoint").(string)
972+
config.WorkbenchBasePath = d.Get("workbench_custom_endpoint").(string)
967973
config.WorkflowsBasePath = d.Get("workflows_custom_endpoint").(string)
968974

969975
// Handwritten Products / Versioned / Atypical Entries

google/provider/provider_mmv1_resources.go

+9-3
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ import (
108108
"github.com/hashicorp/terraform-provider-google/google/services/vertexai"
109109
"github.com/hashicorp/terraform-provider-google/google/services/vmwareengine"
110110
"github.com/hashicorp/terraform-provider-google/google/services/vpcaccess"
111+
"github.com/hashicorp/terraform-provider-google/google/services/workbench"
111112
"github.com/hashicorp/terraform-provider-google/google/services/workflows"
112113

113114
"github.com/hashicorp/terraform-provider-google/google/services/composer"
@@ -343,6 +344,7 @@ var generatedIAMDatasources = map[string]*schema.Resource{
343344
"google_storage_bucket_iam_policy": tpgiamresource.DataSourceIamPolicy(storage.StorageBucketIamSchema, storage.StorageBucketIamUpdaterProducer),
344345
"google_tags_tag_key_iam_policy": tpgiamresource.DataSourceIamPolicy(tags.TagsTagKeyIamSchema, tags.TagsTagKeyIamUpdaterProducer),
345346
"google_tags_tag_value_iam_policy": tpgiamresource.DataSourceIamPolicy(tags.TagsTagValueIamSchema, tags.TagsTagValueIamUpdaterProducer),
347+
"google_workbench_instance_iam_policy": tpgiamresource.DataSourceIamPolicy(workbench.WorkbenchInstanceIamSchema, workbench.WorkbenchInstanceIamUpdaterProducer),
346348
// ####### END generated IAM datasources ###########
347349
}
348350

@@ -371,9 +373,9 @@ var handwrittenIAMDatasources = map[string]*schema.Resource{
371373
}
372374

373375
// Resources
374-
// Generated resources: 349
375-
// Generated IAM resources: 216
376-
// Total generated resources: 565
376+
// Generated resources: 350
377+
// Generated IAM resources: 219
378+
// Total generated resources: 569
377379
var generatedResources = map[string]*schema.Resource{
378380
"google_folder_access_approval_settings": accessapproval.ResourceAccessApprovalFolderSettings(),
379381
"google_organization_access_approval_settings": accessapproval.ResourceAccessApprovalOrganizationSettings(),
@@ -921,6 +923,10 @@ var generatedResources = map[string]*schema.Resource{
921923
"google_vmwareengine_private_cloud": vmwareengine.ResourceVmwareenginePrivateCloud(),
922924
"google_vmwareengine_subnet": vmwareengine.ResourceVmwareengineSubnet(),
923925
"google_vpc_access_connector": vpcaccess.ResourceVPCAccessConnector(),
926+
"google_workbench_instance": workbench.ResourceWorkbenchInstance(),
927+
"google_workbench_instance_iam_binding": tpgiamresource.ResourceIamBinding(workbench.WorkbenchInstanceIamSchema, workbench.WorkbenchInstanceIamUpdaterProducer, workbench.WorkbenchInstanceIdParseFunc),
928+
"google_workbench_instance_iam_member": tpgiamresource.ResourceIamMember(workbench.WorkbenchInstanceIamSchema, workbench.WorkbenchInstanceIamUpdaterProducer, workbench.WorkbenchInstanceIdParseFunc),
929+
"google_workbench_instance_iam_policy": tpgiamresource.ResourceIamPolicy(workbench.WorkbenchInstanceIamSchema, workbench.WorkbenchInstanceIamUpdaterProducer, workbench.WorkbenchInstanceIdParseFunc),
924930
"google_workflows_workflow": workflows.ResourceWorkflowsWorkflow(),
925931
}
926932

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
// ----------------------------------------------------------------------------
5+
//
6+
// *** AUTO GENERATED CODE *** Type: MMv1 ***
7+
//
8+
// ----------------------------------------------------------------------------
9+
//
10+
// This file is automatically generated by Magic Modules and manual
11+
// changes will be clobbered when the file is regenerated.
12+
//
13+
// Please read more about how to change this file in
14+
// .github/CONTRIBUTING.md.
15+
//
16+
// ----------------------------------------------------------------------------
17+
18+
package workbench
19+
20+
import (
21+
"fmt"
22+
23+
"github.com/hashicorp/errwrap"
24+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
25+
"google.golang.org/api/cloudresourcemanager/v1"
26+
27+
"github.com/hashicorp/terraform-provider-google/google/tpgiamresource"
28+
"github.com/hashicorp/terraform-provider-google/google/tpgresource"
29+
transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport"
30+
)
31+
32+
var WorkbenchInstanceIamSchema = map[string]*schema.Schema{
33+
"project": {
34+
Type: schema.TypeString,
35+
Computed: true,
36+
Optional: true,
37+
ForceNew: true,
38+
},
39+
"location": {
40+
Type: schema.TypeString,
41+
Computed: true,
42+
Optional: true,
43+
ForceNew: true,
44+
},
45+
"name": {
46+
Type: schema.TypeString,
47+
Required: true,
48+
ForceNew: true,
49+
DiffSuppressFunc: tpgresource.CompareSelfLinkOrResourceName,
50+
},
51+
}
52+
53+
type WorkbenchInstanceIamUpdater struct {
54+
project string
55+
location string
56+
name string
57+
d tpgresource.TerraformResourceData
58+
Config *transport_tpg.Config
59+
}
60+
61+
func WorkbenchInstanceIamUpdaterProducer(d tpgresource.TerraformResourceData, config *transport_tpg.Config) (tpgiamresource.ResourceIamUpdater, error) {
62+
values := make(map[string]string)
63+
64+
project, _ := tpgresource.GetProject(d, config)
65+
if project != "" {
66+
if err := d.Set("project", project); err != nil {
67+
return nil, fmt.Errorf("Error setting project: %s", err)
68+
}
69+
}
70+
values["project"] = project
71+
location, _ := tpgresource.GetLocation(d, config)
72+
if location != "" {
73+
if err := d.Set("location", location); err != nil {
74+
return nil, fmt.Errorf("Error setting location: %s", err)
75+
}
76+
}
77+
values["location"] = location
78+
if v, ok := d.GetOk("name"); ok {
79+
values["name"] = v.(string)
80+
}
81+
82+
// We may have gotten either a long or short name, so attempt to parse long name if possible
83+
m, err := tpgresource.GetImportIdQualifiers([]string{"projects/(?P<project>[^/]+)/locations/(?P<location>[^/]+)/instances/(?P<name>[^/]+)", "(?P<project>[^/]+)/(?P<location>[^/]+)/(?P<name>[^/]+)", "(?P<location>[^/]+)/(?P<name>[^/]+)", "(?P<name>[^/]+)"}, d, config, d.Get("name").(string))
84+
if err != nil {
85+
return nil, err
86+
}
87+
88+
for k, v := range m {
89+
values[k] = v
90+
}
91+
92+
u := &WorkbenchInstanceIamUpdater{
93+
project: values["project"],
94+
location: values["location"],
95+
name: values["name"],
96+
d: d,
97+
Config: config,
98+
}
99+
100+
if err := d.Set("project", u.project); err != nil {
101+
return nil, fmt.Errorf("Error setting project: %s", err)
102+
}
103+
if err := d.Set("location", u.location); err != nil {
104+
return nil, fmt.Errorf("Error setting location: %s", err)
105+
}
106+
if err := d.Set("name", u.GetResourceId()); err != nil {
107+
return nil, fmt.Errorf("Error setting name: %s", err)
108+
}
109+
110+
return u, nil
111+
}
112+
113+
func WorkbenchInstanceIdParseFunc(d *schema.ResourceData, config *transport_tpg.Config) error {
114+
values := make(map[string]string)
115+
116+
project, _ := tpgresource.GetProject(d, config)
117+
if project != "" {
118+
values["project"] = project
119+
}
120+
121+
location, _ := tpgresource.GetLocation(d, config)
122+
if location != "" {
123+
values["location"] = location
124+
}
125+
126+
m, err := tpgresource.GetImportIdQualifiers([]string{"projects/(?P<project>[^/]+)/locations/(?P<location>[^/]+)/instances/(?P<name>[^/]+)", "(?P<project>[^/]+)/(?P<location>[^/]+)/(?P<name>[^/]+)", "(?P<location>[^/]+)/(?P<name>[^/]+)", "(?P<name>[^/]+)"}, d, config, d.Id())
127+
if err != nil {
128+
return err
129+
}
130+
131+
for k, v := range m {
132+
values[k] = v
133+
}
134+
135+
u := &WorkbenchInstanceIamUpdater{
136+
project: values["project"],
137+
location: values["location"],
138+
name: values["name"],
139+
d: d,
140+
Config: config,
141+
}
142+
if err := d.Set("name", u.GetResourceId()); err != nil {
143+
return fmt.Errorf("Error setting name: %s", err)
144+
}
145+
d.SetId(u.GetResourceId())
146+
return nil
147+
}
148+
149+
func (u *WorkbenchInstanceIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) {
150+
url, err := u.qualifyInstanceUrl("getIamPolicy")
151+
if err != nil {
152+
return nil, err
153+
}
154+
155+
project, err := tpgresource.GetProject(u.d, u.Config)
156+
if err != nil {
157+
return nil, err
158+
}
159+
var obj map[string]interface{}
160+
161+
userAgent, err := tpgresource.GenerateUserAgentString(u.d, u.Config.UserAgent)
162+
if err != nil {
163+
return nil, err
164+
}
165+
166+
policy, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
167+
Config: u.Config,
168+
Method: "GET",
169+
Project: project,
170+
RawURL: url,
171+
UserAgent: userAgent,
172+
Body: obj,
173+
})
174+
if err != nil {
175+
return nil, errwrap.Wrapf(fmt.Sprintf("Error retrieving IAM policy for %s: {{err}}", u.DescribeResource()), err)
176+
}
177+
178+
out := &cloudresourcemanager.Policy{}
179+
err = tpgresource.Convert(policy, out)
180+
if err != nil {
181+
return nil, errwrap.Wrapf("Cannot convert a policy to a resource manager policy: {{err}}", err)
182+
}
183+
184+
return out, nil
185+
}
186+
187+
func (u *WorkbenchInstanceIamUpdater) SetResourceIamPolicy(policy *cloudresourcemanager.Policy) error {
188+
json, err := tpgresource.ConvertToMap(policy)
189+
if err != nil {
190+
return err
191+
}
192+
193+
obj := make(map[string]interface{})
194+
obj["policy"] = json
195+
196+
url, err := u.qualifyInstanceUrl("setIamPolicy")
197+
if err != nil {
198+
return err
199+
}
200+
project, err := tpgresource.GetProject(u.d, u.Config)
201+
if err != nil {
202+
return err
203+
}
204+
205+
userAgent, err := tpgresource.GenerateUserAgentString(u.d, u.Config.UserAgent)
206+
if err != nil {
207+
return err
208+
}
209+
210+
_, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
211+
Config: u.Config,
212+
Method: "POST",
213+
Project: project,
214+
RawURL: url,
215+
UserAgent: userAgent,
216+
Body: obj,
217+
Timeout: u.d.Timeout(schema.TimeoutCreate),
218+
})
219+
if err != nil {
220+
return errwrap.Wrapf(fmt.Sprintf("Error setting IAM policy for %s: {{err}}", u.DescribeResource()), err)
221+
}
222+
223+
return nil
224+
}
225+
226+
func (u *WorkbenchInstanceIamUpdater) qualifyInstanceUrl(methodIdentifier string) (string, error) {
227+
urlTemplate := fmt.Sprintf("{{WorkbenchBasePath}}%s:%s", fmt.Sprintf("projects/%s/locations/%s/instances/%s", u.project, u.location, u.name), methodIdentifier)
228+
url, err := tpgresource.ReplaceVars(u.d, u.Config, urlTemplate)
229+
if err != nil {
230+
return "", err
231+
}
232+
return url, nil
233+
}
234+
235+
func (u *WorkbenchInstanceIamUpdater) GetResourceId() string {
236+
return fmt.Sprintf("projects/%s/locations/%s/instances/%s", u.project, u.location, u.name)
237+
}
238+
239+
func (u *WorkbenchInstanceIamUpdater) GetMutexKey() string {
240+
return fmt.Sprintf("iam-workbench-instance-%s", u.GetResourceId())
241+
}
242+
243+
func (u *WorkbenchInstanceIamUpdater) DescribeResource() string {
244+
return fmt.Sprintf("workbench instance %q", u.GetResourceId())
245+
}

0 commit comments

Comments
 (0)