Skip to content

Commit 3768aee

Browse files
authored
tgc-revival: get cai asset name for iam resources (#15492)
1 parent 3f63311 commit 3768aee

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

mmv1/third_party/terraform/acctest/resource_inventory_reader.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ var (
3030
cachePopulated = false
3131
// Mutex to protect cache access
3232
cacheMutex sync.RWMutex
33+
34+
iamSuffixes = []string{
35+
"_iam_member",
36+
"_iam_binding",
37+
"_iam_policy",
38+
}
3339
)
3440

3541
// PopulateMetadataCache walks through all metadata files once and populates
@@ -77,14 +83,25 @@ func PopulateMetadataCache() error {
7783
return nil
7884
}
7985

86+
iamResources := make([]string, 0)
87+
for _, suffix := range iamSuffixes {
88+
iamResources = append(iamResources, fmt.Sprintf("%s%s", metadata.Resource, suffix))
89+
}
90+
8091
// Store API service name in cache
8192
if metadata.ApiServiceName != "" {
8293
ApiServiceNameCache.Set(metadata.Resource, metadata.ApiServiceName)
94+
for _, iamResource := range iamResources {
95+
ApiServiceNameCache.Set(iamResource, metadata.ApiServiceName)
96+
}
8397
apiNameCount++
8498
}
8599

86100
if metadata.CaiAssetNameFormat != "" {
87101
CaiAssetNameFormatCache.Set(metadata.Resource, metadata.CaiAssetNameFormat)
102+
for _, iamResource := range iamResources {
103+
CaiAssetNameFormatCache.Set(iamResource, metadata.CaiAssetNameFormat)
104+
}
88105
}
89106

90107
// Extract and store service package in cache
@@ -100,6 +117,9 @@ func PopulateMetadataCache() error {
100117
if servicesIndex >= 0 && len(pathParts) > servicesIndex+1 {
101118
servicePackage := pathParts[servicesIndex+1] // The part after "services"
102119
ServicePackageCache.Set(metadata.Resource, servicePackage)
120+
for _, iamResource := range iamResources {
121+
ServicePackageCache.Set(iamResource, servicePackage)
122+
}
103123
servicePkgCount++
104124
}
105125
}

mmv1/third_party/terraform/acctest/tgc_utils.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ type ResourceMetadata struct {
2121
ResourceAddress string `json:"resource_address"`
2222
ImportMetadata ImportMetadata `json:"import_metadata,omitempty"`
2323
Service string `json:"service"`
24+
CaiContentType string `json:"cai_content_type,omitempty"`
2425
}
2526

2627
type ImportMetadata struct {
@@ -83,6 +84,14 @@ func CollectAllTgcMetadata(tgcPayload TgcMetadataPayload) resource.TestCheckFunc
8384

8485
// Process each resource to get CAI asset names and resolve auto IDs
8586
for address, metadata := range tgcPayload.ResourceMetadata {
87+
// https://cloud.google.com/asset-inventory/docs/reference/rest/v1/feeds#ContentType
88+
isIamResource := IsIamResource(metadata.ResourceType)
89+
if isIamResource {
90+
metadata.CaiContentType = "IAM_POLICY"
91+
} else {
92+
metadata.CaiContentType = "RESOURCE"
93+
}
94+
8695
// If there is import metadata update our primary resource
8796
if metadata.ImportMetadata.Id != "" {
8897
tgcPayload.PrimaryResource = address
@@ -116,6 +125,10 @@ func CollectAllTgcMetadata(tgcPayload TgcMetadataPayload) resource.TestCheckFunc
116125
rName = strings.Replace(rName, projectId, projectNumber, 1)
117126
}
118127

128+
if isIamResource {
129+
rName = getIamResourceId(metadata.ResourceType, rName)
130+
}
131+
119132
metadata.CaiAssetNames = []string{fmt.Sprintf("//%s/%s", apiServiceName, rName)}
120133
}
121134
} else {
@@ -320,3 +333,26 @@ func extendWithTGCData(t *testing.T, c resource.TestCase) resource.TestCase {
320333
c.Steps = updatedSteps
321334
return c
322335
}
336+
337+
// Gets IAM resource Id by removing the IAM role and member binding information from id
338+
// id "projects/local-mediator-361721/zones/us-central1-a/instances/tf-test-my-instancev8xqssrek2/roles/compute.osLogin/user:[email protected]"
339+
// will become "projects/local-mediator-361721/zones/us-central1-a/instances/tf-test-my-instancev8xqssrek2"
340+
func getIamResourceId(resourceType, id string) string {
341+
parts := strings.Split(id, "/roles/")
342+
343+
if len(parts) > 0 {
344+
return parts[0]
345+
}
346+
347+
return id
348+
}
349+
350+
// Checks if a resource is an IAM resource
351+
func IsIamResource(resourceType string) bool {
352+
for _, suffix := range iamSuffixes {
353+
if strings.HasSuffix(resourceType, suffix) {
354+
return true
355+
}
356+
}
357+
return false
358+
}

0 commit comments

Comments
 (0)