github.com/khulnasoft-lab/defsec@v1.0.5-0.20230827010352-5e9f46893d95/internal/adapters/terraform/google/iam/adapt.go (about)

     1  package iam
     2  
     3  import (
     4  	"github.com/google/uuid"
     5  	"github.com/khulnasoft-lab/defsec/pkg/providers/google/iam"
     6  	"github.com/khulnasoft-lab/defsec/pkg/terraform"
     7  	"github.com/khulnasoft-lab/defsec/pkg/types"
     8  )
     9  
    10  func Adapt(modules terraform.Modules) iam.IAM {
    11  	return (&adapter{
    12  		orgs:    make(map[string]iam.Organization),
    13  		modules: modules,
    14  	}).Adapt()
    15  }
    16  
    17  type adapter struct {
    18  	modules                       terraform.Modules
    19  	orgs                          map[string]iam.Organization
    20  	folders                       []parentedFolder
    21  	projects                      []parentedProject
    22  	workloadIdentityPoolProviders []iam.WorkloadIdentityPoolProvider
    23  }
    24  
    25  func (a *adapter) Adapt() iam.IAM {
    26  	a.adaptOrganizationIAM()
    27  	a.adaptFolders()
    28  	a.adaptFolderIAM()
    29  	a.adaptProjects()
    30  	a.adaptProjectIAM()
    31  	a.adaptWorkloadIdentityPoolProviders()
    32  	return a.merge()
    33  }
    34  
    35  func (a *adapter) addOrg(blockID string) {
    36  	if _, ok := a.orgs[blockID]; !ok {
    37  		a.orgs[blockID] = iam.Organization{
    38  			Metadata: types.NewUnmanagedMetadata(),
    39  		}
    40  	}
    41  }
    42  
    43  func (a *adapter) merge() iam.IAM {
    44  
    45  	// add projects to folders, orgs
    46  PROJECT:
    47  	for _, project := range a.projects {
    48  		for i, folder := range a.folders {
    49  			if project.folderBlockID != "" && project.folderBlockID == folder.blockID {
    50  				folder.folder.Projects = append(folder.folder.Projects, project.project)
    51  				a.folders[i] = folder
    52  				continue PROJECT
    53  			}
    54  		}
    55  		if project.orgBlockID != "" {
    56  			if org, ok := a.orgs[project.orgBlockID]; ok {
    57  				org.Projects = append(org.Projects, project.project)
    58  				a.orgs[project.orgBlockID] = org
    59  				continue PROJECT
    60  			}
    61  		}
    62  
    63  		org := iam.Organization{
    64  			Metadata: types.NewUnmanagedMetadata(),
    65  			Projects: []iam.Project{project.project},
    66  		}
    67  		a.orgs[uuid.NewString()] = org
    68  	}
    69  
    70  	// add folders to folders, orgs
    71  FOLDER_NESTED:
    72  	for _, folder := range a.folders {
    73  		for i, existing := range a.folders {
    74  			if folder.parentBlockID != "" && folder.parentBlockID == existing.blockID {
    75  				existing.folder.Folders = append(existing.folder.Folders, folder.folder)
    76  				a.folders[i] = existing
    77  				continue FOLDER_NESTED
    78  			}
    79  
    80  		}
    81  	}
    82  FOLDER_ORG:
    83  	for _, folder := range a.folders {
    84  		if folder.parentBlockID != "" {
    85  			if org, ok := a.orgs[folder.parentBlockID]; ok {
    86  				org.Folders = append(org.Folders, folder.folder)
    87  				a.orgs[folder.parentBlockID] = org
    88  				continue FOLDER_ORG
    89  			}
    90  		} else {
    91  			// add to placeholder?
    92  			org := iam.Organization{
    93  				Metadata: types.NewUnmanagedMetadata(),
    94  				Folders:  []iam.Folder{folder.folder},
    95  			}
    96  			a.orgs[uuid.NewString()] = org
    97  		}
    98  	}
    99  
   100  	output := iam.IAM{
   101  		Organizations:                 nil,
   102  		WorkloadIdentityPoolProviders: a.workloadIdentityPoolProviders,
   103  	}
   104  	for _, org := range a.orgs {
   105  		output.Organizations = append(output.Organizations, org)
   106  	}
   107  	return output
   108  }