diff --git a/go.mod b/go.mod index 3f0213baa..be1bdb474 100644 --- a/go.mod +++ b/go.mod @@ -11,13 +11,13 @@ require ( github.com/hashicorp/hcl/v2 v2.20.1 github.com/hashicorp/terraform-json v0.22.1 github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0 - github.com/hashicorp/terraform-provider-google-beta v1.20.1-0.20240820164214-0ac834396a40 + github.com/hashicorp/terraform-provider-google-beta v1.20.1-0.20240820232428-04b789c2f9b2 github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.9.0 github.com/zclconf/go-cty v1.14.4 go.uber.org/zap v1.21.0 - google.golang.org/api v0.190.0 + google.golang.org/api v0.191.0 ) require github.com/spf13/cobra v1.7.0 @@ -26,14 +26,14 @@ require ( bitbucket.org/creachadair/stringset v0.0.11 // indirect cel.dev/expr v0.15.0 // indirect cloud.google.com/go v0.115.0 // indirect - cloud.google.com/go/auth v0.7.3 // indirect + cloud.google.com/go/auth v0.8.0 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.3 // indirect - cloud.google.com/go/bigtable v1.27.2-0.20240730134218-123c88616251 // indirect + cloud.google.com/go/bigtable v1.29.0 // indirect cloud.google.com/go/compute/metadata v0.5.0 // indirect cloud.google.com/go/iam v1.1.12 // indirect cloud.google.com/go/longrunning v0.5.11 // indirect cloud.google.com/go/monitoring v1.20.3 // indirect - github.com/GoogleCloudPlatform/declarative-resource-client-library v1.70.0 // indirect + github.com/GoogleCloudPlatform/declarative-resource-client-library v1.71.0 // indirect github.com/ProtonMail/go-crypto v1.1.0-alpha.2 // indirect github.com/agext/levenshtein v1.2.3 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect @@ -111,11 +111,11 @@ require ( golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 // indirect golang.org/x/mod v0.17.0 // indirect golang.org/x/net v0.27.0 // indirect - golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/sync v0.7.0 // indirect + golang.org/x/oauth2 v0.22.0 // indirect + golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect - golang.org/x/time v0.5.0 // indirect + golang.org/x/time v0.6.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20240730163845-b1a4ccb954bf // indirect diff --git a/go.sum b/go.sum index 4ce480e49..20e329cd4 100644 --- a/go.sum +++ b/go.sum @@ -5,12 +5,12 @@ cel.dev/expr v0.15.0/go.mod h1:TRSuuV7DlVCE/uwv5QbAiW/v8l5O8C4eEPHeu7gf7Sg= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14= cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU= -cloud.google.com/go/auth v0.7.3 h1:98Vr+5jMaCZ5NZk6e/uBgf60phTk/XN84r8QEWB9yjY= -cloud.google.com/go/auth v0.7.3/go.mod h1:HJtWUx1P5eqjy/f6Iq5KeytNpbAcGolPhOgyop2LlzA= +cloud.google.com/go/auth v0.8.0 h1:y8jUJLl/Fg+qNBWxP/Hox2ezJvjkrPb952PC1p0G6A4= +cloud.google.com/go/auth v0.8.0/go.mod h1:qGVp/Y3kDRSDZ5gFD/XPUfYQ9xW1iI7q8RIRoCyBbJc= cloud.google.com/go/auth/oauth2adapt v0.2.3 h1:MlxF+Pd3OmSudg/b1yZ5lJwoXCEaeedAguodky1PcKI= cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX5cuhwU+ffUuXRJE8I= -cloud.google.com/go/bigtable v1.27.2-0.20240730134218-123c88616251 h1:OF+V7OrVPhsXy++iTHewE4VD1kv6ikWQJbRIiq1/Kjc= -cloud.google.com/go/bigtable v1.27.2-0.20240730134218-123c88616251/go.mod h1:avmXcmxVbLJAo9moICRYMgDyTTPoV0MA0lHKnyqV4fQ= +cloud.google.com/go/bigtable v1.29.0 h1:2CnFjKPwjpZMZdTi2RpppvxzD80zKzDYrLYEQw/NnAs= +cloud.google.com/go/bigtable v1.29.0/go.mod h1:5p909nNdWaNUcWs6KGZO8mI5HUovstlmrIi7+eA5PTQ= cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= cloud.google.com/go/iam v1.1.12 h1:JixGLimRrNGcxvJEQ8+clfLxPlbeZA6MuRJ+qJNQ5Xw= @@ -22,8 +22,8 @@ cloud.google.com/go/monitoring v1.20.3/go.mod h1:GPIVIdNznIdGqEjtRKQWTLcUeRnPjZW dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/GoogleCloudPlatform/declarative-resource-client-library v1.70.0 h1:dqqxHZYK0tlzViFqAbKzMIkfboQVWYN1CTEM2sjBtmQ= -github.com/GoogleCloudPlatform/declarative-resource-client-library v1.70.0/go.mod h1:pL2Qt5HT+x6xrTd806oMiM3awW6kNIXB/iiuClz6m6k= +github.com/GoogleCloudPlatform/declarative-resource-client-library v1.71.0 h1:vRKCLiR3faPmXAoqSdwXLv28/kygggzaKXzgdm6GXhg= +github.com/GoogleCloudPlatform/declarative-resource-client-library v1.71.0/go.mod h1:pL2Qt5HT+x6xrTd806oMiM3awW6kNIXB/iiuClz6m6k= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/ProtonMail/go-crypto v1.1.0-alpha.2 h1:bkyFVUP+ROOARdgCiJzNQo2V2kiB97LyUpzH9P6Hrlg= @@ -190,8 +190,8 @@ github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0 h1:qHprzXy/As0rxedphECBEQAh github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0/go.mod h1:H+8tjs9TjV2w57QFVSMBQacf8k/E1XwLXGCARgViC6A= github.com/hashicorp/terraform-plugin-testing v1.5.1 h1:T4aQh9JAhmWo4+t1A7x+rnxAJHCDIYW9kXyo4sVO92c= github.com/hashicorp/terraform-plugin-testing v1.5.1/go.mod h1:dg8clO6K59rZ8w9EshBmDp1CxTIPu3yA4iaDpX1h5u0= -github.com/hashicorp/terraform-provider-google-beta v1.20.1-0.20240820164214-0ac834396a40 h1:93h8huZYFPlN4E5gvLW+GhLZxSnC1+dfsja3AW2kY4E= -github.com/hashicorp/terraform-provider-google-beta v1.20.1-0.20240820164214-0ac834396a40/go.mod h1:mbLHS7zKRfkaFt9qpT/cmmwnrB5NSdnz1jpDoAZd6A0= +github.com/hashicorp/terraform-provider-google-beta v1.20.1-0.20240820232428-04b789c2f9b2 h1:MffSs5GmWnt6PxnJctKByXuN+xU3JJpfo6P7bkNXNig= +github.com/hashicorp/terraform-provider-google-beta v1.20.1-0.20240820232428-04b789c2f9b2/go.mod h1:IkI2dOHongwQ2RIUyitBH4rDJvYBuClAoFCheApCTpY= github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI= github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= @@ -361,8 +361,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= -golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= +golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -370,8 +370,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -403,8 +403,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= +golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -422,8 +422,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.190.0 h1:ASM+IhLY1zljNdLu19W1jTmU6A+gMk6M46Wlur61s+Q= -google.golang.org/api v0.190.0/go.mod h1:QIr6I9iedBLnfqoD6L6Vze1UvS5Hzj5r2aUBOaZnLHo= +google.golang.org/api v0.191.0 h1:cJcF09Z+4HAB2t5qTQM1ZtfL/PemsLFkcFG67qq2afk= +google.golang.org/api v0.191.0/go.mod h1:tD5dsFGxFza0hnQveGfVk9QQYKcfp+VzgRqyXFxE0+E= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= diff --git a/tfplan2cai/ancestrymanager/ancestrymanager.go b/tfplan2cai/ancestrymanager/ancestrymanager.go index baf00c2a5..728da882c 100644 --- a/tfplan2cai/ancestrymanager/ancestrymanager.go +++ b/tfplan2cai/ancestrymanager/ancestrymanager.go @@ -18,6 +18,13 @@ import ( "go.uber.org/zap" ) +const ( + projectPrefix = "projects/" + folderPrefix = "folders/" + orgPrefix = "organizations/" + unknownOrg = orgPrefix + "unknown" +) + // AncestryManager is the interface that fetch ancestors for a resource. type AncestryManager interface { // Ancestors returns a list of ancestors. @@ -73,8 +80,11 @@ func (m *manager) initAncestryCache(entries map[string]string) error { if err != nil { return err } - // ancestry path should include the item itself - if ancestors[0] != key { + // The ancestry path should include the item itself, unless both the key and ancestor + // have the projects/ prefix, indicating the key is a project ID and the ancestry is + // project number. CAI ancestors use the project number, so that is preferred if it + // is available. + if ancestors[0] != key && !(strings.HasPrefix(key, projectPrefix) && strings.HasPrefix(ancestors[0], projectPrefix)) { ancestors = append([]string{key}, ancestors...) } m.store(key, ancestors) @@ -88,7 +98,7 @@ func parseAncestryKey(val string) (string, error) { ix := strings.LastIndex(key, "/") if ix == -1 { // If not containing /, then treat it as a project. - return fmt.Sprintf("projects/%s", key), nil + return projectPrefix + key, nil } else { k := key[:ix] if k == "projects" || k == "folders" || k == "organizations" { @@ -127,24 +137,15 @@ func (m *manager) fetchAncestors(config *transport_tpg.Config, tfData tpgresourc orgID, orgOK := getOrganizationFromResource(tfData) if orgOK { - orgKey = orgID - if !strings.HasPrefix(orgKey, "organizations/") { - orgKey = fmt.Sprintf("organizations/%s", orgKey) - } + orgKey = ensurePrefix(orgID, orgPrefix) } folderID, folderOK := getFolderFromResource(tfData) if folderOK { - folderKey = folderID - if !strings.HasPrefix(folderKey, "folders/") { - folderKey = fmt.Sprintf("folders/%s", folderKey) - } + folderKey = ensurePrefix(folderID, folderPrefix) } project, _ := m.getProjectFromResource(tfData, config, cai) if project != "" { - projectKey = project - if !strings.HasPrefix(projectKey, "projects/") { - projectKey = fmt.Sprintf("projects/%s", project) - } + projectKey = ensurePrefix(project, projectPrefix) } switch cai.Type { @@ -154,7 +155,7 @@ func (m *manager) fetchAncestors(config *transport_tpg.Config, tfData tpgresourc } else if orgOK { key = orgKey } else { - return []string{"organizations/unknown"}, nil + return []string{unknownOrg}, nil } case "cloudresourcemanager.googleapis.com/Organization": if !orgOK { @@ -168,7 +169,7 @@ func (m *manager) fetchAncestors(config *transport_tpg.Config, tfData tpgresourc } else if projectKey != "" { key = projectKey } else { - return []string{"organizations/unknown"}, nil + return []string{unknownOrg}, nil } case "cloudresourcemanager.googleapis.com/Project", "cloudbilling.googleapis.com/ProjectBillingInfo": // for google_project and google_project_iam resources @@ -183,7 +184,7 @@ func (m *manager) fetchAncestors(config *transport_tpg.Config, tfData tpgresourc // only folder_id or org_id is allowed for google_project if orgOK { // no need to use API to fetch ancestors - ancestors = append(ancestors, fmt.Sprintf("organizations/%s", orgID)) + ancestors = append(ancestors, orgPrefix+orgID) return ancestors, nil } if folderOK { @@ -199,13 +200,13 @@ func (m *manager) fetchAncestors(config *transport_tpg.Config, tfData tpgresourc // neither folder_id nor org_id is specified if projectKey == "" { - return []string{"organizations/unknown"}, nil + return []string{unknownOrg}, nil } key = projectKey default: if projectKey == "" { - return []string{"organizations/unknown"}, nil + return []string{unknownOrg}, nil } key = projectKey } @@ -220,16 +221,16 @@ func (m *manager) getAncestorsWithCache(key string) ([]string, error) { ancestors = append(ancestors, cachedAncestors...) break } - if strings.HasPrefix(cur, "organizations/") { + if strings.HasPrefix(cur, orgPrefix) { ancestors = append(ancestors, cur) break } if m.resourceManagerV3 == nil || m.resourceManagerV1 == nil { return nil, fmt.Errorf("resourceManager required to fetch ancestry for %s from the API", cur) } - if strings.HasPrefix(cur, "projects") { + if strings.HasPrefix(cur, projectPrefix) { // fall back to use v1 API GetAncestry to avoid requiring extra folder permission - projectID := strings.TrimPrefix(cur, "projects/") + projectID := strings.TrimPrefix(cur, projectPrefix) var resp *crmv1.GetAncestryResponse var err error err = transport_tpg.Retry(transport_tpg.RetryOptions{ @@ -325,9 +326,9 @@ func normalizeAncestry(val string) string { old string new string }{ - {"organization/", "organizations/"}, - {"folder/", "folders/"}, - {"project/", "projects/"}, + {"organization/", orgPrefix}, + {"folder/", folderPrefix}, + {"project/", projectPrefix}, } { val = strings.ReplaceAll(val, r.old, r.new) } @@ -383,3 +384,10 @@ type NoOpAncestryManager struct{} func (*NoOpAncestryManager) Ancestors(config *transport_tpg.Config, tfData tpgresource.TerraformResourceData, cai *resources.Asset) ([]string, string, error) { return nil, "", nil } + +func ensurePrefix(s, pre string) string { + if strings.HasPrefix(s, pre) { + return s + } + return pre + s +} diff --git a/tfplan2cai/ancestrymanager/ancestrymanager_test.go b/tfplan2cai/ancestrymanager/ancestrymanager_test.go index c47166e14..59bbe4f52 100644 --- a/tfplan2cai/ancestrymanager/ancestrymanager_test.go +++ b/tfplan2cai/ancestrymanager/ancestrymanager_test.go @@ -1032,6 +1032,8 @@ func TestParseAncestryPath_Fail(t *testing.T) { } func TestInitAncestryCache(t *testing.T) { + t.Parallel() + tests := []struct { name string entries map[string]string @@ -1082,9 +1084,23 @@ func TestInitAncestryCache(t *testing.T) { "organizations/123": {"organizations/123"}, }, }, + { + name: "project id key with project number ancestry", + entries: map[string]string{ + "projects/test-proj": "organizations/456/projects/123", + }, + want: map[string][]string{ + "projects/test-proj": {"projects/123", "organizations/456"}, + "projects/123": {"projects/123", "organizations/456"}, + "organizations/456": {"organizations/456"}, + }, + }, } for _, test := range tests { + test := test t.Run(test.name, func(t *testing.T) { + t.Parallel() + m := &manager{ ancestorCache: make(map[string][]string), } diff --git a/tfplan2cai/converters/google/resources/resource_converters.go b/tfplan2cai/converters/google/resources/resource_converters.go index f2a2784da..514e2716f 100644 --- a/tfplan2cai/converters/google/resources/resource_converters.go +++ b/tfplan2cai/converters/google/resources/resource_converters.go @@ -339,6 +339,9 @@ func ResourceConverters() map[string][]cai.ResourceConverter { "google_iap_web_iam_policy": {iap.ResourceConverterIapWebIamPolicy()}, "google_iap_web_iam_binding": {iap.ResourceConverterIapWebIamBinding()}, "google_iap_web_iam_member": {iap.ResourceConverterIapWebIamMember()}, + "google_kms_ekm_connection_iam_policy": {kms.ResourceConverterKMSEkmConnectionIamPolicy()}, + "google_kms_ekm_connection_iam_binding": {kms.ResourceConverterKMSEkmConnectionIamBinding()}, + "google_kms_ekm_connection_iam_member": {kms.ResourceConverterKMSEkmConnectionIamMember()}, "google_logging_log_view_iam_policy": {logging.ResourceConverterLoggingLogViewIamPolicy()}, "google_logging_log_view_iam_binding": {logging.ResourceConverterLoggingLogViewIamBinding()}, "google_logging_log_view_iam_member": {logging.ResourceConverterLoggingLogViewIamMember()}, diff --git a/tfplan2cai/converters/google/resources/services/bigquery/iam_bigquery_table.go b/tfplan2cai/converters/google/resources/services/bigquery/iam_bigquery_table.go index fe65a336a..82fd37ab0 100644 --- a/tfplan2cai/converters/google/resources/services/bigquery/iam_bigquery_table.go +++ b/tfplan2cai/converters/google/resources/services/bigquery/iam_bigquery_table.go @@ -145,11 +145,6 @@ func (u *BigQueryTableIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager. return nil, err } var obj map[string]interface{} - obj = map[string]interface{}{ - "options": map[string]interface{}{ - "requestedPolicyVersion": 1, - }, - } userAgent, err := tpgresource.GenerateUserAgentString(u.d, u.Config.UserAgent) if err != nil { diff --git a/tfplan2cai/converters/google/resources/services/cloudquotas/cloudquotas_quota_preference.go b/tfplan2cai/converters/google/resources/services/cloudquotas/cloudquotas_quota_preference.go index c184b01f2..00e9604cd 100644 --- a/tfplan2cai/converters/google/resources/services/cloudquotas/cloudquotas_quota_preference.go +++ b/tfplan2cai/converters/google/resources/services/cloudquotas/cloudquotas_quota_preference.go @@ -179,7 +179,7 @@ func expandCloudQuotasQuotaPreferenceQuotaConfigGrantedValue(v interface{}, d tp } func expandCloudQuotasQuotaPreferenceQuotaConfigTraceId(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { - return v, nil + return nil, nil } func expandCloudQuotasQuotaPreferenceQuotaConfigAnnotations(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { diff --git a/tfplan2cai/converters/google/resources/services/compute/compute_subnetwork.go b/tfplan2cai/converters/google/resources/services/compute/compute_subnetwork.go index 22a959508..581e78d3a 100644 --- a/tfplan2cai/converters/google/resources/services/compute/compute_subnetwork.go +++ b/tfplan2cai/converters/google/resources/services/compute/compute_subnetwork.go @@ -17,6 +17,7 @@ package compute import ( "context" "fmt" + "log" "net" "reflect" @@ -48,6 +49,37 @@ func IsShrinkageIpCidr(_ context.Context, old, new, _ interface{}) bool { return true } +func sendSecondaryIpRangeIfEmptyDiff(_ context.Context, diff *schema.ResourceDiff, meta interface{}) error { + // on create, return immediately as we don't need to determine if the value is empty or not + if diff.Id() == "" { + return nil + } + + sendZero := diff.Get("send_secondary_ip_range_if_empty").(bool) + if !sendZero { + return nil + } + + configSecondaryIpRange := diff.GetRawConfig().GetAttr("secondary_ip_range") + if !configSecondaryIpRange.IsKnown() { + return nil + } + configValueIsEmpty := configSecondaryIpRange.IsNull() || configSecondaryIpRange.LengthInt() == 0 + + stateSecondaryIpRange := diff.GetRawState().GetAttr("secondary_ip_range") + if !stateSecondaryIpRange.IsKnown() { + return nil + } + stateValueIsEmpty := stateSecondaryIpRange.IsNull() || stateSecondaryIpRange.LengthInt() == 0 + + if configValueIsEmpty && !stateValueIsEmpty { + log.Printf("[DEBUG] setting secondary_ip_range to newly empty") + diff.SetNew("secondary_ip_range", make([]interface{}, 0)) + } + + return nil +} + const ComputeSubnetworkAssetType string = "compute.googleapis.com/Subnetwork" func ResourceConverterComputeSubnetwork() cai.ResourceConverter { diff --git a/tfplan2cai/converters/google/resources/services/discoveryengine/discoveryengine_schema.go b/tfplan2cai/converters/google/resources/services/discoveryengine/discoveryengine_schema.go new file mode 100644 index 000000000..b565b4bfb --- /dev/null +++ b/tfplan2cai/converters/google/resources/services/discoveryengine/discoveryengine_schema.go @@ -0,0 +1,69 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package discoveryengine + +import ( + "reflect" + + "github.com/GoogleCloudPlatform/terraform-google-conversion/v5/tfplan2cai/converters/google/resources/cai" + "github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google-beta/google-beta/transport" +) + +const DiscoveryEngineSchemaAssetType string = "{{location}}-discoveryengine.googleapis.com/Schema" + +func ResourceConverterDiscoveryEngineSchema() cai.ResourceConverter { + return cai.ResourceConverter{ + AssetType: DiscoveryEngineSchemaAssetType, + Convert: GetDiscoveryEngineSchemaCaiObject, + } +} + +func GetDiscoveryEngineSchemaCaiObject(d tpgresource.TerraformResourceData, config *transport_tpg.Config) ([]cai.Asset, error) { + name, err := cai.AssetName(d, config, "//{{location}}-discoveryengine.googleapis.com/projects/{{project}}/locations/{{location}}/collections/default_collection/dataStores/{{data_store_id}}/schemas/{{schema_id}}") + if err != nil { + return []cai.Asset{}, err + } + if obj, err := GetDiscoveryEngineSchemaApiObject(d, config); err == nil { + return []cai.Asset{{ + Name: name, + Type: DiscoveryEngineSchemaAssetType, + Resource: &cai.AssetResource{ + Version: "v1", + DiscoveryDocumentURI: "https://www.googleapis.com/discovery/v1/apis/{{location}}-discoveryengine/v1/rest", + DiscoveryName: "Schema", + Data: obj, + }, + }}, nil + } else { + return []cai.Asset{}, err + } +} + +func GetDiscoveryEngineSchemaApiObject(d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]interface{}, error) { + obj := make(map[string]interface{}) + jsonSchemaProp, err := expandDiscoveryEngineSchemaJsonSchema(d.Get("json_schema"), d, config) + if err != nil { + return nil, err + } else if v, ok := d.GetOkExists("json_schema"); !tpgresource.IsEmptyValue(reflect.ValueOf(jsonSchemaProp)) && (ok || !reflect.DeepEqual(v, jsonSchemaProp)) { + obj["jsonSchema"] = jsonSchemaProp + } + + return obj, nil +} + +func expandDiscoveryEngineSchemaJsonSchema(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} diff --git a/tfplan2cai/converters/google/resources/services/kms/iam_kms_ekm_connection.go b/tfplan2cai/converters/google/resources/services/kms/iam_kms_ekm_connection.go new file mode 100644 index 000000000..d8bdc058f --- /dev/null +++ b/tfplan2cai/converters/google/resources/services/kms/iam_kms_ekm_connection.go @@ -0,0 +1,246 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package kms + +import ( + "fmt" + + "github.com/hashicorp/errwrap" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "google.golang.org/api/cloudresourcemanager/v1" + + "github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgiamresource" + "github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google-beta/google-beta/transport" +) + +var KMSEkmConnectionIamSchema = map[string]*schema.Schema{ + "project": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + }, + "location": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + }, + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + DiffSuppressFunc: tpgresource.CompareSelfLinkOrResourceName, + }, +} + +type KMSEkmConnectionIamUpdater struct { + project string + location string + name string + d tpgresource.TerraformResourceData + Config *transport_tpg.Config +} + +func KMSEkmConnectionIamUpdaterProducer(d tpgresource.TerraformResourceData, config *transport_tpg.Config) (tpgiamresource.ResourceIamUpdater, error) { + values := make(map[string]string) + + project, _ := tpgresource.GetProject(d, config) + if project != "" { + if err := d.Set("project", project); err != nil { + return nil, fmt.Errorf("Error setting project: %s", err) + } + } + values["project"] = project + location, _ := tpgresource.GetLocation(d, config) + if location != "" { + if err := d.Set("location", location); err != nil { + return nil, fmt.Errorf("Error setting location: %s", err) + } + } + values["location"] = location + if v, ok := d.GetOk("name"); ok { + values["name"] = v.(string) + } + + // We may have gotten either a long or short name, so attempt to parse long name if possible + m, err := tpgresource.GetImportIdQualifiers([]string{"projects/(?P[^/]+)/locations/(?P[^/]+)/ekmConnections/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)"}, d, config, d.Get("name").(string)) + if err != nil { + return nil, err + } + + for k, v := range m { + values[k] = v + } + + u := &KMSEkmConnectionIamUpdater{ + project: values["project"], + location: values["location"], + name: values["name"], + d: d, + Config: config, + } + + if err := d.Set("project", u.project); err != nil { + return nil, fmt.Errorf("Error setting project: %s", err) + } + if err := d.Set("location", u.location); err != nil { + return nil, fmt.Errorf("Error setting location: %s", err) + } + if err := d.Set("name", u.GetResourceId()); err != nil { + return nil, fmt.Errorf("Error setting name: %s", err) + } + + return u, nil +} + +func KMSEkmConnectionIdParseFunc(d *schema.ResourceData, config *transport_tpg.Config) error { + values := make(map[string]string) + + project, _ := tpgresource.GetProject(d, config) + if project != "" { + values["project"] = project + } + + location, _ := tpgresource.GetLocation(d, config) + if location != "" { + values["location"] = location + } + + m, err := tpgresource.GetImportIdQualifiers([]string{"projects/(?P[^/]+)/locations/(?P[^/]+)/ekmConnections/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)"}, d, config, d.Id()) + if err != nil { + return err + } + + for k, v := range m { + values[k] = v + } + + u := &KMSEkmConnectionIamUpdater{ + project: values["project"], + location: values["location"], + name: values["name"], + d: d, + Config: config, + } + if err := d.Set("name", u.GetResourceId()); err != nil { + return fmt.Errorf("Error setting name: %s", err) + } + d.SetId(u.GetResourceId()) + return nil +} + +func (u *KMSEkmConnectionIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) { + url, err := u.qualifyEkmConnectionUrl("getIamPolicy") + if err != nil { + return nil, err + } + + project, err := tpgresource.GetProject(u.d, u.Config) + if err != nil { + return nil, err + } + var obj map[string]interface{} + url, err = transport_tpg.AddQueryParams(url, map[string]string{"options.requestedPolicyVersion": fmt.Sprintf("%d", tpgiamresource.IamPolicyVersion)}) + if err != nil { + return nil, err + } + + userAgent, err := tpgresource.GenerateUserAgentString(u.d, u.Config.UserAgent) + if err != nil { + return nil, err + } + + policy, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: u.Config, + Method: "GET", + Project: project, + RawURL: url, + UserAgent: userAgent, + Body: obj, + }) + if err != nil { + return nil, errwrap.Wrapf(fmt.Sprintf("Error retrieving IAM policy for %s: {{err}}", u.DescribeResource()), err) + } + + out := &cloudresourcemanager.Policy{} + err = tpgresource.Convert(policy, out) + if err != nil { + return nil, errwrap.Wrapf("Cannot convert a policy to a resource manager policy: {{err}}", err) + } + + return out, nil +} + +func (u *KMSEkmConnectionIamUpdater) SetResourceIamPolicy(policy *cloudresourcemanager.Policy) error { + json, err := tpgresource.ConvertToMap(policy) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + obj["policy"] = json + + url, err := u.qualifyEkmConnectionUrl("setIamPolicy") + if err != nil { + return err + } + project, err := tpgresource.GetProject(u.d, u.Config) + if err != nil { + return err + } + + userAgent, err := tpgresource.GenerateUserAgentString(u.d, u.Config.UserAgent) + if err != nil { + return err + } + + _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: u.Config, + Method: "POST", + Project: project, + RawURL: url, + UserAgent: userAgent, + Body: obj, + Timeout: u.d.Timeout(schema.TimeoutCreate), + }) + if err != nil { + return errwrap.Wrapf(fmt.Sprintf("Error setting IAM policy for %s: {{err}}", u.DescribeResource()), err) + } + + return nil +} + +func (u *KMSEkmConnectionIamUpdater) qualifyEkmConnectionUrl(methodIdentifier string) (string, error) { + urlTemplate := fmt.Sprintf("{{KMSBasePath}}%s:%s", fmt.Sprintf("projects/%s/locations/%s/ekmConnections/%s", u.project, u.location, u.name), methodIdentifier) + url, err := tpgresource.ReplaceVars(u.d, u.Config, urlTemplate) + if err != nil { + return "", err + } + return url, nil +} + +func (u *KMSEkmConnectionIamUpdater) GetResourceId() string { + return fmt.Sprintf("projects/%s/locations/%s/ekmConnections/%s", u.project, u.location, u.name) +} + +func (u *KMSEkmConnectionIamUpdater) GetMutexKey() string { + return fmt.Sprintf("iam-kms-ekmconnection-%s", u.GetResourceId()) +} + +func (u *KMSEkmConnectionIamUpdater) DescribeResource() string { + return fmt.Sprintf("kms ekmconnection %q", u.GetResourceId()) +} diff --git a/tfplan2cai/converters/google/resources/services/kms/kms_ekm_connection_iam.go b/tfplan2cai/converters/google/resources/services/kms/kms_ekm_connection_iam.go new file mode 100644 index 000000000..0984cf5b4 --- /dev/null +++ b/tfplan2cai/converters/google/resources/services/kms/kms_ekm_connection_iam.go @@ -0,0 +1,129 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package kms + +import ( + "fmt" + + "github.com/GoogleCloudPlatform/terraform-google-conversion/v5/tfplan2cai/converters/google/resources/cai" + "github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google-beta/google-beta/transport" +) + +// Provide a separate asset type constant so we don't have to worry about name conflicts between IAM and non-IAM converter files +const KMSEkmConnectionIAMAssetType string = "cloudkms.googleapis.com/EkmConnection" + +func ResourceConverterKMSEkmConnectionIamPolicy() cai.ResourceConverter { + return cai.ResourceConverter{ + AssetType: KMSEkmConnectionIAMAssetType, + Convert: GetKMSEkmConnectionIamPolicyCaiObject, + MergeCreateUpdate: MergeKMSEkmConnectionIamPolicy, + } +} + +func ResourceConverterKMSEkmConnectionIamBinding() cai.ResourceConverter { + return cai.ResourceConverter{ + AssetType: KMSEkmConnectionIAMAssetType, + Convert: GetKMSEkmConnectionIamBindingCaiObject, + FetchFullResource: FetchKMSEkmConnectionIamPolicy, + MergeCreateUpdate: MergeKMSEkmConnectionIamBinding, + MergeDelete: MergeKMSEkmConnectionIamBindingDelete, + } +} + +func ResourceConverterKMSEkmConnectionIamMember() cai.ResourceConverter { + return cai.ResourceConverter{ + AssetType: KMSEkmConnectionIAMAssetType, + Convert: GetKMSEkmConnectionIamMemberCaiObject, + FetchFullResource: FetchKMSEkmConnectionIamPolicy, + MergeCreateUpdate: MergeKMSEkmConnectionIamMember, + MergeDelete: MergeKMSEkmConnectionIamMemberDelete, + } +} + +func GetKMSEkmConnectionIamPolicyCaiObject(d tpgresource.TerraformResourceData, config *transport_tpg.Config) ([]cai.Asset, error) { + return newKMSEkmConnectionIamAsset(d, config, cai.ExpandIamPolicyBindings) +} + +func GetKMSEkmConnectionIamBindingCaiObject(d tpgresource.TerraformResourceData, config *transport_tpg.Config) ([]cai.Asset, error) { + return newKMSEkmConnectionIamAsset(d, config, cai.ExpandIamRoleBindings) +} + +func GetKMSEkmConnectionIamMemberCaiObject(d tpgresource.TerraformResourceData, config *transport_tpg.Config) ([]cai.Asset, error) { + return newKMSEkmConnectionIamAsset(d, config, cai.ExpandIamMemberBindings) +} + +func MergeKMSEkmConnectionIamPolicy(existing, incoming cai.Asset) cai.Asset { + existing.IAMPolicy = incoming.IAMPolicy + return existing +} + +func MergeKMSEkmConnectionIamBinding(existing, incoming cai.Asset) cai.Asset { + return cai.MergeIamAssets(existing, incoming, cai.MergeAuthoritativeBindings) +} + +func MergeKMSEkmConnectionIamBindingDelete(existing, incoming cai.Asset) cai.Asset { + return cai.MergeDeleteIamAssets(existing, incoming, cai.MergeDeleteAuthoritativeBindings) +} + +func MergeKMSEkmConnectionIamMember(existing, incoming cai.Asset) cai.Asset { + return cai.MergeIamAssets(existing, incoming, cai.MergeAdditiveBindings) +} + +func MergeKMSEkmConnectionIamMemberDelete(existing, incoming cai.Asset) cai.Asset { + return cai.MergeDeleteIamAssets(existing, incoming, cai.MergeDeleteAdditiveBindings) +} + +func newKMSEkmConnectionIamAsset( + d tpgresource.TerraformResourceData, + config *transport_tpg.Config, + expandBindings func(d tpgresource.TerraformResourceData) ([]cai.IAMBinding, error), +) ([]cai.Asset, error) { + bindings, err := expandBindings(d) + if err != nil { + return []cai.Asset{}, fmt.Errorf("expanding bindings: %v", err) + } + + name, err := cai.AssetName(d, config, "//cloudkms.googleapis.com/projects/{{project}}/locations/{{location}}/ekmConnections/{{name}}") + if err != nil { + return []cai.Asset{}, err + } + + return []cai.Asset{{ + Name: name, + Type: KMSEkmConnectionIAMAssetType, + IAMPolicy: &cai.IAMPolicy{ + Bindings: bindings, + }, + }}, nil +} + +func FetchKMSEkmConnectionIamPolicy(d tpgresource.TerraformResourceData, config *transport_tpg.Config) (cai.Asset, error) { + // Check if the identity field returns a value + if _, ok := d.GetOk("location"); !ok { + return cai.Asset{}, cai.ErrEmptyIdentityField + } + if _, ok := d.GetOk("name"); !ok { + return cai.Asset{}, cai.ErrEmptyIdentityField + } + + return cai.FetchIamPolicy( + KMSEkmConnectionIamUpdaterProducer, + d, + config, + "//cloudkms.googleapis.com/projects/{{project}}/locations/{{location}}/ekmConnections/{{name}}", + KMSEkmConnectionIAMAssetType, + ) +} diff --git a/tfplan2cai/converters/google/resources/services/networkservices/networkservices_tcp_route.go b/tfplan2cai/converters/google/resources/services/networkservices/networkservices_tcp_route.go index 6b835b069..3799cb6b8 100644 --- a/tfplan2cai/converters/google/resources/services/networkservices/networkservices_tcp_route.go +++ b/tfplan2cai/converters/google/resources/services/networkservices/networkservices_tcp_route.go @@ -189,6 +189,13 @@ func expandNetworkServicesTcpRouteRulesAction(v interface{}, d tpgresource.Terra transformed["originalDestination"] = transformedOriginalDestination } + transformedIdleTimeout, err := expandNetworkServicesTcpRouteRulesActionIdleTimeout(original["idle_timeout"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedIdleTimeout); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["idleTimeout"] = transformedIdleTimeout + } + return transformed, nil } @@ -233,6 +240,10 @@ func expandNetworkServicesTcpRouteRulesActionOriginalDestination(v interface{}, return v, nil } +func expandNetworkServicesTcpRouteRulesActionIdleTimeout(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + func expandNetworkServicesTcpRouteEffectiveLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { if v == nil { return map[string]string{}, nil diff --git a/tfplan2cai/converters/google/resources/services/parallelstore/parallelstore_instance.go b/tfplan2cai/converters/google/resources/services/parallelstore/parallelstore_instance.go index b2eb5d36e..81b688f41 100644 --- a/tfplan2cai/converters/google/resources/services/parallelstore/parallelstore_instance.go +++ b/tfplan2cai/converters/google/resources/services/parallelstore/parallelstore_instance.go @@ -78,6 +78,18 @@ func GetParallelstoreInstanceApiObject(d tpgresource.TerraformResourceData, conf } else if v, ok := d.GetOkExists("reserved_ip_range"); !tpgresource.IsEmptyValue(reflect.ValueOf(reservedIpRangeProp)) && (ok || !reflect.DeepEqual(v, reservedIpRangeProp)) { obj["reservedIpRange"] = reservedIpRangeProp } + fileStripeLevelProp, err := expandParallelstoreInstanceFileStripeLevel(d.Get("file_stripe_level"), d, config) + if err != nil { + return nil, err + } else if v, ok := d.GetOkExists("file_stripe_level"); !tpgresource.IsEmptyValue(reflect.ValueOf(fileStripeLevelProp)) && (ok || !reflect.DeepEqual(v, fileStripeLevelProp)) { + obj["fileStripeLevel"] = fileStripeLevelProp + } + directoryStripeLevelProp, err := expandParallelstoreInstanceDirectoryStripeLevel(d.Get("directory_stripe_level"), d, config) + if err != nil { + return nil, err + } else if v, ok := d.GetOkExists("directory_stripe_level"); !tpgresource.IsEmptyValue(reflect.ValueOf(directoryStripeLevelProp)) && (ok || !reflect.DeepEqual(v, directoryStripeLevelProp)) { + obj["directoryStripeLevel"] = directoryStripeLevelProp + } labelsProp, err := expandParallelstoreInstanceEffectiveLabels(d.Get("effective_labels"), d, config) if err != nil { return nil, err @@ -104,6 +116,14 @@ func expandParallelstoreInstanceReservedIpRange(v interface{}, d tpgresource.Ter return v, nil } +func expandParallelstoreInstanceFileStripeLevel(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandParallelstoreInstanceDirectoryStripeLevel(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + func expandParallelstoreInstanceEffectiveLabels(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { if v == nil { return map[string]string{}, nil diff --git a/tfplan2cai/converters/google/resources/services/securitycenter/securitycenter_folder_notification_config.go b/tfplan2cai/converters/google/resources/services/securitycenter/securitycenter_folder_notification_config.go new file mode 100644 index 000000000..bae9be882 --- /dev/null +++ b/tfplan2cai/converters/google/resources/services/securitycenter/securitycenter_folder_notification_config.go @@ -0,0 +1,108 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package securitycenter + +import ( + "reflect" + + "github.com/GoogleCloudPlatform/terraform-google-conversion/v5/tfplan2cai/converters/google/resources/cai" + "github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google-beta/google-beta/transport" +) + +const SecurityCenterFolderNotificationConfigAssetType string = "securitycenter.googleapis.com/FolderNotificationConfig" + +func ResourceConverterSecurityCenterFolderNotificationConfig() cai.ResourceConverter { + return cai.ResourceConverter{ + AssetType: SecurityCenterFolderNotificationConfigAssetType, + Convert: GetSecurityCenterFolderNotificationConfigCaiObject, + } +} + +func GetSecurityCenterFolderNotificationConfigCaiObject(d tpgresource.TerraformResourceData, config *transport_tpg.Config) ([]cai.Asset, error) { + name, err := cai.AssetName(d, config, "//securitycenter.googleapis.com/folders/{{folder}}/notificationConfigs/{{config_id}}") + if err != nil { + return []cai.Asset{}, err + } + if obj, err := GetSecurityCenterFolderNotificationConfigApiObject(d, config); err == nil { + return []cai.Asset{{ + Name: name, + Type: SecurityCenterFolderNotificationConfigAssetType, + Resource: &cai.AssetResource{ + Version: "v1", + DiscoveryDocumentURI: "https://www.googleapis.com/discovery/v1/apis/securitycenter/v1/rest", + DiscoveryName: "FolderNotificationConfig", + Data: obj, + }, + }}, nil + } else { + return []cai.Asset{}, err + } +} + +func GetSecurityCenterFolderNotificationConfigApiObject(d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]interface{}, error) { + obj := make(map[string]interface{}) + descriptionProp, err := expandSecurityCenterFolderNotificationConfigDescription(d.Get("description"), d, config) + if err != nil { + return nil, err + } else if v, ok := d.GetOkExists("description"); !tpgresource.IsEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { + obj["description"] = descriptionProp + } + pubsubTopicProp, err := expandSecurityCenterFolderNotificationConfigPubsubTopic(d.Get("pubsub_topic"), d, config) + if err != nil { + return nil, err + } else if v, ok := d.GetOkExists("pubsub_topic"); !tpgresource.IsEmptyValue(reflect.ValueOf(pubsubTopicProp)) && (ok || !reflect.DeepEqual(v, pubsubTopicProp)) { + obj["pubsubTopic"] = pubsubTopicProp + } + streamingConfigProp, err := expandSecurityCenterFolderNotificationConfigStreamingConfig(d.Get("streaming_config"), d, config) + if err != nil { + return nil, err + } else if v, ok := d.GetOkExists("streaming_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(streamingConfigProp)) && (ok || !reflect.DeepEqual(v, streamingConfigProp)) { + obj["streamingConfig"] = streamingConfigProp + } + + return obj, nil +} + +func expandSecurityCenterFolderNotificationConfigDescription(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandSecurityCenterFolderNotificationConfigPubsubTopic(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandSecurityCenterFolderNotificationConfigStreamingConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedFilter, err := expandSecurityCenterFolderNotificationConfigStreamingConfigFilter(original["filter"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedFilter); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["filter"] = transformedFilter + } + + return transformed, nil +} + +func expandSecurityCenterFolderNotificationConfigStreamingConfigFilter(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} diff --git a/tfplan2cai/converters/google/resources/services/securitycenterv2/securitycenterv2_folder_notification_config.go b/tfplan2cai/converters/google/resources/services/securitycenterv2/securitycenterv2_folder_notification_config.go new file mode 100644 index 000000000..3490342d8 --- /dev/null +++ b/tfplan2cai/converters/google/resources/services/securitycenterv2/securitycenterv2_folder_notification_config.go @@ -0,0 +1,108 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package securitycenterv2 + +import ( + "reflect" + + "github.com/GoogleCloudPlatform/terraform-google-conversion/v5/tfplan2cai/converters/google/resources/cai" + "github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google-beta/google-beta/transport" +) + +const SecurityCenterV2FolderNotificationConfigAssetType string = "securitycenter.googleapis.com/FolderNotificationConfig" + +func ResourceConverterSecurityCenterV2FolderNotificationConfig() cai.ResourceConverter { + return cai.ResourceConverter{ + AssetType: SecurityCenterV2FolderNotificationConfigAssetType, + Convert: GetSecurityCenterV2FolderNotificationConfigCaiObject, + } +} + +func GetSecurityCenterV2FolderNotificationConfigCaiObject(d tpgresource.TerraformResourceData, config *transport_tpg.Config) ([]cai.Asset, error) { + name, err := cai.AssetName(d, config, "//securitycenter.googleapis.com/folders/{{folder}}/locations/{{location}}/notificationConfigs/{{config_id}}") + if err != nil { + return []cai.Asset{}, err + } + if obj, err := GetSecurityCenterV2FolderNotificationConfigApiObject(d, config); err == nil { + return []cai.Asset{{ + Name: name, + Type: SecurityCenterV2FolderNotificationConfigAssetType, + Resource: &cai.AssetResource{ + Version: "v2", + DiscoveryDocumentURI: "https://www.googleapis.com/discovery/v1/apis/securitycenter/v2/rest", + DiscoveryName: "FolderNotificationConfig", + Data: obj, + }, + }}, nil + } else { + return []cai.Asset{}, err + } +} + +func GetSecurityCenterV2FolderNotificationConfigApiObject(d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]interface{}, error) { + obj := make(map[string]interface{}) + descriptionProp, err := expandSecurityCenterV2FolderNotificationConfigDescription(d.Get("description"), d, config) + if err != nil { + return nil, err + } else if v, ok := d.GetOkExists("description"); !tpgresource.IsEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { + obj["description"] = descriptionProp + } + pubsubTopicProp, err := expandSecurityCenterV2FolderNotificationConfigPubsubTopic(d.Get("pubsub_topic"), d, config) + if err != nil { + return nil, err + } else if v, ok := d.GetOkExists("pubsub_topic"); !tpgresource.IsEmptyValue(reflect.ValueOf(pubsubTopicProp)) && (ok || !reflect.DeepEqual(v, pubsubTopicProp)) { + obj["pubsubTopic"] = pubsubTopicProp + } + streamingConfigProp, err := expandSecurityCenterV2FolderNotificationConfigStreamingConfig(d.Get("streaming_config"), d, config) + if err != nil { + return nil, err + } else if v, ok := d.GetOkExists("streaming_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(streamingConfigProp)) && (ok || !reflect.DeepEqual(v, streamingConfigProp)) { + obj["streamingConfig"] = streamingConfigProp + } + + return obj, nil +} + +func expandSecurityCenterV2FolderNotificationConfigDescription(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandSecurityCenterV2FolderNotificationConfigPubsubTopic(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandSecurityCenterV2FolderNotificationConfigStreamingConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedFilter, err := expandSecurityCenterV2FolderNotificationConfigStreamingConfigFilter(original["filter"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedFilter); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["filter"] = transformedFilter + } + + return transformed, nil +} + +func expandSecurityCenterV2FolderNotificationConfigStreamingConfigFilter(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} diff --git a/tfplan2cai/converters/google/resources/services/securitycenterv2/securitycenterv2_organization_scc_big_query_exports.go b/tfplan2cai/converters/google/resources/services/securitycenterv2/securitycenterv2_organization_scc_big_query_exports.go new file mode 100644 index 000000000..276920c4e --- /dev/null +++ b/tfplan2cai/converters/google/resources/services/securitycenterv2/securitycenterv2_organization_scc_big_query_exports.go @@ -0,0 +1,99 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package securitycenterv2 + +import ( + "reflect" + + "github.com/GoogleCloudPlatform/terraform-google-conversion/v5/tfplan2cai/converters/google/resources/cai" + "github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google-beta/google-beta/transport" +) + +const SecurityCenterV2OrganizationSccBigQueryExportsAssetType string = "securitycenter.googleapis.com/OrganizationSccBigQueryExports" + +func ResourceConverterSecurityCenterV2OrganizationSccBigQueryExports() cai.ResourceConverter { + return cai.ResourceConverter{ + AssetType: SecurityCenterV2OrganizationSccBigQueryExportsAssetType, + Convert: GetSecurityCenterV2OrganizationSccBigQueryExportsCaiObject, + } +} + +func GetSecurityCenterV2OrganizationSccBigQueryExportsCaiObject(d tpgresource.TerraformResourceData, config *transport_tpg.Config) ([]cai.Asset, error) { + name, err := cai.AssetName(d, config, "//securitycenter.googleapis.com/organizations/{{organization}}/locations/{{location}}/bigQueryExports/{{big_query_export_id}}") + if err != nil { + return []cai.Asset{}, err + } + if obj, err := GetSecurityCenterV2OrganizationSccBigQueryExportsApiObject(d, config); err == nil { + return []cai.Asset{{ + Name: name, + Type: SecurityCenterV2OrganizationSccBigQueryExportsAssetType, + Resource: &cai.AssetResource{ + Version: "v2", + DiscoveryDocumentURI: "https://www.googleapis.com/discovery/v1/apis/securitycenter/v2/rest", + DiscoveryName: "OrganizationSccBigQueryExports", + Data: obj, + }, + }}, nil + } else { + return []cai.Asset{}, err + } +} + +func GetSecurityCenterV2OrganizationSccBigQueryExportsApiObject(d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]interface{}, error) { + obj := make(map[string]interface{}) + nameProp, err := expandSecurityCenterV2OrganizationSccBigQueryExportsName(d.Get("name"), d, config) + if err != nil { + return nil, err + } else if v, ok := d.GetOkExists("name"); !tpgresource.IsEmptyValue(reflect.ValueOf(nameProp)) && (ok || !reflect.DeepEqual(v, nameProp)) { + obj["name"] = nameProp + } + descriptionProp, err := expandSecurityCenterV2OrganizationSccBigQueryExportsDescription(d.Get("description"), d, config) + if err != nil { + return nil, err + } else if v, ok := d.GetOkExists("description"); !tpgresource.IsEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) { + obj["description"] = descriptionProp + } + datasetProp, err := expandSecurityCenterV2OrganizationSccBigQueryExportsDataset(d.Get("dataset"), d, config) + if err != nil { + return nil, err + } else if v, ok := d.GetOkExists("dataset"); !tpgresource.IsEmptyValue(reflect.ValueOf(datasetProp)) && (ok || !reflect.DeepEqual(v, datasetProp)) { + obj["dataset"] = datasetProp + } + filterProp, err := expandSecurityCenterV2OrganizationSccBigQueryExportsFilter(d.Get("filter"), d, config) + if err != nil { + return nil, err + } else if v, ok := d.GetOkExists("filter"); !tpgresource.IsEmptyValue(reflect.ValueOf(filterProp)) && (ok || !reflect.DeepEqual(v, filterProp)) { + obj["filter"] = filterProp + } + + return obj, nil +} + +func expandSecurityCenterV2OrganizationSccBigQueryExportsName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandSecurityCenterV2OrganizationSccBigQueryExportsDescription(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandSecurityCenterV2OrganizationSccBigQueryExportsDataset(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandSecurityCenterV2OrganizationSccBigQueryExportsFilter(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} diff --git a/tfplan2cai/converters/google/resources/services/vertexai/vertexai_index_endpoint_deployed_index.go b/tfplan2cai/converters/google/resources/services/vertexai/vertexai_index_endpoint_deployed_index.go new file mode 100644 index 000000000..12138d0ad --- /dev/null +++ b/tfplan2cai/converters/google/resources/services/vertexai/vertexai_index_endpoint_deployed_index.go @@ -0,0 +1,298 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package vertexai + +import ( + "reflect" + + "github.com/GoogleCloudPlatform/terraform-google-conversion/v5/tfplan2cai/converters/google/resources/cai" + "github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google-beta/google-beta/transport" +) + +const VertexAIIndexEndpointDeployedIndexAssetType string = "aiplatform.googleapis.com/IndexEndpointDeployedIndex" + +func ResourceConverterVertexAIIndexEndpointDeployedIndex() cai.ResourceConverter { + return cai.ResourceConverter{ + AssetType: VertexAIIndexEndpointDeployedIndexAssetType, + Convert: GetVertexAIIndexEndpointDeployedIndexCaiObject, + } +} + +func GetVertexAIIndexEndpointDeployedIndexCaiObject(d tpgresource.TerraformResourceData, config *transport_tpg.Config) ([]cai.Asset, error) { + name, err := cai.AssetName(d, config, "//aiplatform.googleapis.com/{{index_endpoint}}") + if err != nil { + return []cai.Asset{}, err + } + if obj, err := GetVertexAIIndexEndpointDeployedIndexApiObject(d, config); err == nil { + return []cai.Asset{{ + Name: name, + Type: VertexAIIndexEndpointDeployedIndexAssetType, + Resource: &cai.AssetResource{ + Version: "v1beta1", + DiscoveryDocumentURI: "https://www.googleapis.com/discovery/v1/apis/aiplatform/v1beta1/rest", + DiscoveryName: "IndexEndpointDeployedIndex", + Data: obj, + }, + }}, nil + } else { + return []cai.Asset{}, err + } +} + +func GetVertexAIIndexEndpointDeployedIndexApiObject(d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]interface{}, error) { + obj := make(map[string]interface{}) + deployedIndexIdProp, err := expandVertexAIIndexEndpointDeployedIndexDeployedIndexId(d.Get("deployed_index_id"), d, config) + if err != nil { + return nil, err + } else if v, ok := d.GetOkExists("deployed_index_id"); !tpgresource.IsEmptyValue(reflect.ValueOf(deployedIndexIdProp)) && (ok || !reflect.DeepEqual(v, deployedIndexIdProp)) { + obj["deployedIndexId"] = deployedIndexIdProp + } + indexProp, err := expandVertexAIIndexEndpointDeployedIndexIndex(d.Get("index"), d, config) + if err != nil { + return nil, err + } else if v, ok := d.GetOkExists("index"); !tpgresource.IsEmptyValue(reflect.ValueOf(indexProp)) && (ok || !reflect.DeepEqual(v, indexProp)) { + obj["index"] = indexProp + } + displayNameProp, err := expandVertexAIIndexEndpointDeployedIndexDisplayName(d.Get("display_name"), d, config) + if err != nil { + return nil, err + } else if v, ok := d.GetOkExists("display_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(displayNameProp)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { + obj["displayName"] = displayNameProp + } + automaticResourcesProp, err := expandVertexAIIndexEndpointDeployedIndexAutomaticResources(d.Get("automatic_resources"), d, config) + if err != nil { + return nil, err + } else if v, ok := d.GetOkExists("automatic_resources"); !tpgresource.IsEmptyValue(reflect.ValueOf(automaticResourcesProp)) && (ok || !reflect.DeepEqual(v, automaticResourcesProp)) { + obj["automaticResources"] = automaticResourcesProp + } + dedicatedResourcesProp, err := expandVertexAIIndexEndpointDeployedIndexDedicatedResources(d.Get("dedicated_resources"), d, config) + if err != nil { + return nil, err + } else if v, ok := d.GetOkExists("dedicated_resources"); !tpgresource.IsEmptyValue(reflect.ValueOf(dedicatedResourcesProp)) && (ok || !reflect.DeepEqual(v, dedicatedResourcesProp)) { + obj["dedicatedResources"] = dedicatedResourcesProp + } + enableAccessLoggingProp, err := expandVertexAIIndexEndpointDeployedIndexEnableAccessLogging(d.Get("enable_access_logging"), d, config) + if err != nil { + return nil, err + } else if v, ok := d.GetOkExists("enable_access_logging"); !tpgresource.IsEmptyValue(reflect.ValueOf(enableAccessLoggingProp)) && (ok || !reflect.DeepEqual(v, enableAccessLoggingProp)) { + obj["enableAccessLogging"] = enableAccessLoggingProp + } + deployedIndexAuthConfigProp, err := expandVertexAIIndexEndpointDeployedIndexDeployedIndexAuthConfig(d.Get("deployed_index_auth_config"), d, config) + if err != nil { + return nil, err + } else if v, ok := d.GetOkExists("deployed_index_auth_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(deployedIndexAuthConfigProp)) && (ok || !reflect.DeepEqual(v, deployedIndexAuthConfigProp)) { + obj["deployedIndexAuthConfig"] = deployedIndexAuthConfigProp + } + reservedIpRangesProp, err := expandVertexAIIndexEndpointDeployedIndexReservedIpRanges(d.Get("reserved_ip_ranges"), d, config) + if err != nil { + return nil, err + } else if v, ok := d.GetOkExists("reserved_ip_ranges"); !tpgresource.IsEmptyValue(reflect.ValueOf(reservedIpRangesProp)) && (ok || !reflect.DeepEqual(v, reservedIpRangesProp)) { + obj["reservedIpRanges"] = reservedIpRangesProp + } + deploymentGroupProp, err := expandVertexAIIndexEndpointDeployedIndexDeploymentGroup(d.Get("deployment_group"), d, config) + if err != nil { + return nil, err + } else if v, ok := d.GetOkExists("deployment_group"); !tpgresource.IsEmptyValue(reflect.ValueOf(deploymentGroupProp)) && (ok || !reflect.DeepEqual(v, deploymentGroupProp)) { + obj["deploymentGroup"] = deploymentGroupProp + } + + return resourceVertexAIIndexEndpointDeployedIndexEncoder(d, config, obj) +} + +func resourceVertexAIIndexEndpointDeployedIndexEncoder(d tpgresource.TerraformResourceData, meta interface{}, obj map[string]interface{}) (map[string]interface{}, error) { + req := make(map[string]interface{}) + obj["id"] = d.Get("deployed_index_id") + delete(obj, "deployedIndexId") + delete(obj, "name") + delete(obj, "indexEndpoint") + req["deployedIndex"] = obj + return req, nil +} + +func expandVertexAIIndexEndpointDeployedIndexDeployedIndexId(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandVertexAIIndexEndpointDeployedIndexIndex(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandVertexAIIndexEndpointDeployedIndexDisplayName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandVertexAIIndexEndpointDeployedIndexAutomaticResources(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedMinReplicaCount, err := expandVertexAIIndexEndpointDeployedIndexAutomaticResourcesMinReplicaCount(original["min_replica_count"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMinReplicaCount); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["minReplicaCount"] = transformedMinReplicaCount + } + + transformedMaxReplicaCount, err := expandVertexAIIndexEndpointDeployedIndexAutomaticResourcesMaxReplicaCount(original["max_replica_count"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMaxReplicaCount); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["maxReplicaCount"] = transformedMaxReplicaCount + } + + return transformed, nil +} + +func expandVertexAIIndexEndpointDeployedIndexAutomaticResourcesMinReplicaCount(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandVertexAIIndexEndpointDeployedIndexAutomaticResourcesMaxReplicaCount(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandVertexAIIndexEndpointDeployedIndexDedicatedResources(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedMachineSpec, err := expandVertexAIIndexEndpointDeployedIndexDedicatedResourcesMachineSpec(original["machine_spec"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMachineSpec); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["machineSpec"] = transformedMachineSpec + } + + transformedMinReplicaCount, err := expandVertexAIIndexEndpointDeployedIndexDedicatedResourcesMinReplicaCount(original["min_replica_count"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMinReplicaCount); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["minReplicaCount"] = transformedMinReplicaCount + } + + transformedMaxReplicaCount, err := expandVertexAIIndexEndpointDeployedIndexDedicatedResourcesMaxReplicaCount(original["max_replica_count"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMaxReplicaCount); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["maxReplicaCount"] = transformedMaxReplicaCount + } + + return transformed, nil +} + +func expandVertexAIIndexEndpointDeployedIndexDedicatedResourcesMachineSpec(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedMachineType, err := expandVertexAIIndexEndpointDeployedIndexDedicatedResourcesMachineSpecMachineType(original["machine_type"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedMachineType); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["machineType"] = transformedMachineType + } + + return transformed, nil +} + +func expandVertexAIIndexEndpointDeployedIndexDedicatedResourcesMachineSpecMachineType(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandVertexAIIndexEndpointDeployedIndexDedicatedResourcesMinReplicaCount(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandVertexAIIndexEndpointDeployedIndexDedicatedResourcesMaxReplicaCount(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandVertexAIIndexEndpointDeployedIndexEnableAccessLogging(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandVertexAIIndexEndpointDeployedIndexDeployedIndexAuthConfig(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedAuthProvider, err := expandVertexAIIndexEndpointDeployedIndexDeployedIndexAuthConfigAuthProvider(original["auth_provider"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAuthProvider); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["authProvider"] = transformedAuthProvider + } + + return transformed, nil +} + +func expandVertexAIIndexEndpointDeployedIndexDeployedIndexAuthConfigAuthProvider(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedAudiences, err := expandVertexAIIndexEndpointDeployedIndexDeployedIndexAuthConfigAuthProviderAudiences(original["audiences"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAudiences); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["audiences"] = transformedAudiences + } + + transformedAllowedIssuers, err := expandVertexAIIndexEndpointDeployedIndexDeployedIndexAuthConfigAuthProviderAllowedIssuers(original["allowed_issuers"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedAllowedIssuers); val.IsValid() && !tpgresource.IsEmptyValue(val) { + transformed["allowedIssuers"] = transformedAllowedIssuers + } + + return transformed, nil +} + +func expandVertexAIIndexEndpointDeployedIndexDeployedIndexAuthConfigAuthProviderAudiences(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandVertexAIIndexEndpointDeployedIndexDeployedIndexAuthConfigAuthProviderAllowedIssuers(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandVertexAIIndexEndpointDeployedIndexReservedIpRanges(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandVertexAIIndexEndpointDeployedIndexDeploymentGroup(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} diff --git a/tfplan2cai/converters/google/resources/services/workbench/workbench_instance.go b/tfplan2cai/converters/google/resources/services/workbench/workbench_instance.go index 2e1900a0e..77b071eeb 100644 --- a/tfplan2cai/converters/google/resources/services/workbench/workbench_instance.go +++ b/tfplan2cai/converters/google/resources/services/workbench/workbench_instance.go @@ -55,6 +55,7 @@ var WorkbenchInstanceProvidedMetadata = []string{ "agent-health-check-interval-seconds", "agent-health-check-path", "container", + "cos-update-strategy", "custom-container-image", "custom-container-payload", "data-disk-uri", @@ -73,6 +74,7 @@ var WorkbenchInstanceProvidedMetadata = []string{ "generate-diagnostics-bucket", "generate-diagnostics-file", "generate-diagnostics-options", + "google-logging-enabled", "image-url", "install-monitoring-agent", "install-nvidia-driver", @@ -95,6 +97,7 @@ var WorkbenchInstanceProvidedMetadata = []string{ "report-system-status", "restriction", "serial-port-logging-enable", + "service-account-mode", "shutdown-script", "title", "use-collaborative",