Skip to content

Commit 212355d

Browse files
authored
tgc-revival: add google_compute_region_health_check (#15234)
1 parent 77b6ea7 commit 212355d

File tree

5 files changed

+159
-56
lines changed

5 files changed

+159
-56
lines changed

mmv1/api/resource.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1992,9 +1992,8 @@ func (r Resource) DefineAssetTypeForResourceInProduct() bool {
19921992
return true
19931993
}
19941994

1995-
// Gets the Cai asset name template, which could include version
1996-
// For example: //monitoring.googleapis.com/v3/projects/{{project}}/services/{{service_id}}
1997-
func (r Resource) rawCaiAssetNameTemplate(productBackendName string) string {
1995+
// Gets the Cai asset name format
1996+
func (r Resource) GetCaiAssetNameFormat() string {
19981997
caiBaseUrl := ""
19991998
caiId := ""
20001999
if r.CaiIdentity != "" {
@@ -2020,7 +2019,13 @@ func (r Resource) rawCaiAssetNameTemplate(productBackendName string) string {
20202019
caiBaseUrl = fmt.Sprintf("%s/%s", r.BaseUrl, caiIdTemplate)
20212020
}
20222021
}
2023-
return fmt.Sprintf("//%s.googleapis.com/%s", productBackendName, caiBaseUrl)
2022+
return caiBaseUrl
2023+
}
2024+
2025+
// Gets the Cai asset name template, which could include version
2026+
// For example: //monitoring.googleapis.com/v3/projects/{{project}}/services/{{service_id}}
2027+
func (r Resource) rawCaiAssetNameTemplate(productBackendName string) string {
2028+
return fmt.Sprintf("//%s.googleapis.com/%s", productBackendName, r.GetCaiAssetNameFormat())
20242029
}
20252030

20262031
// Guesses the identifier of the resource, as "name" is not always the identifier

mmv1/products/compute/RegionHealthCheck.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ custom_code:
5252
encoder: 'templates/terraform/encoders/health_check_type.tmpl'
5353
custom_diff:
5454
- 'healthCheckCustomizeDiff'
55+
include_in_tgc_next_DO_NOT_USE: true
5556
sweeper:
5657
url_substitutions:
5758
- region: "us-central1"
@@ -117,11 +118,13 @@ examples:
117118
min_version: 'beta'
118119
vars:
119120
health_check_name: 'grpc-with-tls-region-health-check'
121+
tgc_skip_test: 'grpcTlsHealthCheck is not in CAI asset, but is required in this test.'
120122
- name: 'region_health_check_grpc_with_tls_full'
121123
primary_resource_id: 'grpc-with-tls-region-health-check'
122124
min_version: 'beta'
123125
vars:
124126
health_check_name: 'grpc-with-tls-region-health-check'
127+
tgc_skip_test: 'grpcTlsHealthCheck is not in CAI asset, but is required in this test.'
125128
parameters:
126129
- name: 'region'
127130
type: ResourceRef
@@ -878,6 +881,7 @@ properties:
878881
- 'grpc_health_check'
879882
- 'grpc_tls_health_check'
880883
diff_suppress_func: 'portDiffSuppress'
884+
is_missing_in_cai: true
881885
properties:
882886
- name: 'port'
883887
type: Integer

mmv1/provider/terraform_tgc_next.go

Lines changed: 80 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"os"
2424
"path"
2525
"path/filepath"
26+
"regexp"
2627
"strings"
2728
"time"
2829

@@ -53,10 +54,12 @@ type TerraformGoogleConversionNext struct {
5354
}
5455

5556
type ResourceIdentifier struct {
56-
ServiceName string
57-
TerraformName string
58-
ResourceName string
59-
AliasName string // It can be "Default" or the same with ResourceName
57+
ServiceName string
58+
TerraformName string
59+
ResourceName string
60+
AliasName string // It can be "Default" or the same with ResourceName
61+
CaiAssetNameFormat string
62+
IdentityParam string
6063
}
6164

6265
func NewTerraformGoogleConversionNext(product *api.Product, versionName string, startTime time.Time) TerraformGoogleConversionNext {
@@ -170,6 +173,7 @@ func (tgc TerraformGoogleConversionNext) CompileCommonFiles(outputFolder string,
170173

171174
// cai2hcl
172175
"pkg/cai2hcl/converters/resource_converters.go": "templates/tgc_next/cai2hcl/resource_converters.go.tmpl",
176+
"pkg/cai2hcl/converters/convert_resource.go": "templates/tgc_next/cai2hcl/convert_resource.go.tmpl",
173177
}
174178

175179
templateData := NewTemplateData(outputFolder, tgc.TargetVersionName)
@@ -337,10 +341,11 @@ func (tgc *TerraformGoogleConversionNext) generateResourcesForVersion(products [
337341
tgc.ResourceCount++
338342

339343
resourceIdentifier := ResourceIdentifier{
340-
ServiceName: service,
341-
TerraformName: object.TerraformName(),
342-
ResourceName: object.ResourceName(),
343-
AliasName: object.ResourceName(),
344+
ServiceName: service,
345+
TerraformName: object.TerraformName(),
346+
ResourceName: object.ResourceName(),
347+
AliasName: object.ResourceName(),
348+
CaiAssetNameFormat: object.GetCaiAssetNameFormat(),
344349
}
345350
tgc.ResourcesForVersion = append(tgc.ResourcesForVersion, resourceIdentifier)
346351

@@ -360,11 +365,77 @@ func (tgc *TerraformGoogleConversionNext) generateResourcesForVersion(products [
360365
tgc.ResourcesByCaiResourceType[caiResourceType] = []ResourceIdentifier{resourceIdentifier}
361366
}
362367
} else {
363-
tgc.ResourcesByCaiResourceType[caiResourceType] = resources
368+
tgc.ResourcesByCaiResourceType[caiResourceType] = FindIdentityParams(resources)
364369
}
365370
}
366371
}
367372

373+
// Analyzes a list of CAI asset names and finds the single path segment
374+
// (by index) that contains different values across all names.
375+
// Example:
376+
// "folders/{{folder}}/feeds/{{feed_id}}" -> folders
377+
// "organizations/{{org_id}}/feeds/{{feed_id}} -> organizations
378+
// "projects/{{project}}/feeds/{{feed_id}}" -> projects
379+
func FindIdentityParams(rids []ResourceIdentifier) []ResourceIdentifier {
380+
segmentsList := make([][]string, len(rids))
381+
for i, rid := range rids {
382+
urlPath := rid.CaiAssetNameFormat
383+
urlPath = strings.Trim(urlPath, "/")
384+
385+
processedURL := regexp.MustCompile(`\{\{%?(\w+)\}\}`).ReplaceAllString(urlPath, "")
386+
segments := strings.Split(processedURL, "/")
387+
var cleanSegments []string
388+
for _, seg := range segments {
389+
if seg != "" {
390+
cleanSegments = append(cleanSegments, seg)
391+
}
392+
}
393+
394+
segmentsList[i] = cleanSegments
395+
}
396+
397+
if len(segmentsList[0]) == 0 {
398+
return rids
399+
}
400+
expectedLength := len(segmentsList[0])
401+
402+
for i := 1; i < len(segmentsList); i++ {
403+
if len(segmentsList[i]) != expectedLength {
404+
return rids
405+
}
406+
}
407+
408+
varyingIndex := -1
409+
410+
for i := 0; i < expectedLength; i++ {
411+
referenceSegment := segmentsList[0][i]
412+
isVarying := false
413+
414+
for j := 1; j < len(segmentsList); j++ {
415+
if segmentsList[j][i] != referenceSegment {
416+
isVarying = true
417+
break
418+
}
419+
}
420+
421+
if isVarying {
422+
if varyingIndex != -1 {
423+
return rids
424+
}
425+
varyingIndex = i
426+
}
427+
}
428+
429+
if varyingIndex != -1 {
430+
for i, segments := range segmentsList {
431+
rids[i].IdentityParam = segments[varyingIndex]
432+
}
433+
return rids
434+
}
435+
436+
return rids
437+
}
438+
368439
type TgcWithProducts struct {
369440
TerraformGoogleConversionNext
370441
Compiler string
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
{{/* The license inside this block applies to this file
2+
Copyright 2025 Google LLC. All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License. */ -}}
15+
package converters
16+
17+
import (
18+
"strings"
19+
20+
{{- range $resourceType, $resources := $.ResourcesByCaiResourceType}}
21+
{{- if gt (len $resources) 1 }}
22+
"github.com/hashicorp/terraform-provider-google/google/services/{{ (index $resources 0).ServiceName }}"
23+
{{- end }}
24+
{{- end }}
25+
"github.com/GoogleCloudPlatform/terraform-google-conversion/v7/pkg/cai2hcl/models"
26+
"github.com/GoogleCloudPlatform/terraform-google-conversion/v7/pkg/caiasset"
27+
)
28+
29+
func ConvertResource(asset caiasset.Asset) ([]*models.TerraformResourceBlock, error) {
30+
converters, ok := ConverterMap[asset.Type]
31+
if !ok || len(converters) == 0 {
32+
return nil, nil
33+
}
34+
35+
var converter models.Cai2hclConverter
36+
// Normally, one asset type has only one converter.
37+
if len(converters) == 1 {
38+
converter = converters["Default"]
39+
} else {
40+
// Edge cases
41+
// Handle the edge case that multiple Terraform resources share the same CAI asset type
42+
switch asset.Type {
43+
{{- range $resourceType, $resources := $.ResourcesByCaiResourceType}}
44+
{{- if gt (len $resources) 1 }}
45+
case {{ $resourceType }}AssetType:
46+
{{- range $i, $object := $resources }}
47+
{{- if eq $i 0 }}
48+
if strings.Contains(asset.Name, "{{$object.IdentityParam}}") {
49+
{{- else }}
50+
} else if strings.Contains(asset.Name, "{{$object.IdentityParam}}") {
51+
{{- end }}
52+
converter = ConverterMap[asset.Type]["{{ $object.AliasName }}"]
53+
{{- if eq $i (sub (len $resources) 1)}}
54+
}
55+
{{- end }}
56+
{{- end }}
57+
{{- end }}
58+
{{- end }}
59+
}
60+
}
61+
62+
if converter == nil {
63+
return nil, nil
64+
}
65+
return converter.Convert(asset)
66+
}

mmv1/third_party/tgc_next/pkg/cai2hcl/converters/convert_resource.go

Lines changed: 0 additions & 43 deletions
This file was deleted.

0 commit comments

Comments
 (0)