in internal/policygen/iam.go [39:94]
func generateIAMPolicies(rn runner.Runner, resources []*states.Resource, outputPath, templateDir string) error {
bindings, err := allBindings(rn, resources)
if err != nil {
return err
}
for root, rbs := range bindings {
outputFolder := fmt.Sprintf("%s_%s", root.Type, root.ID)
// Generate policies for allowed roles.
data := map[string]interface{}{
// organizations/1234, folders/1234, projects/1234
"target": fmt.Sprintf("%ss/%s", root.Type, root.ID),
"roles": rbs,
// Also prepend type and id in the policy name to make it unique across multiple policies for the same role.
"suffix": fmt.Sprintf("%s_%s", root.Type, root.ID),
}
in := filepath.Join(templateDir, "forseti", "tf_based", "iam_allow_roles.yaml")
out := filepath.Join(outputPath, outputFolder, "iam_allow_roles.yaml")
if err := template.WriteFile(in, out, data); err != nil {
return err
}
// Generate policies for allowed bindings for each role.
for role, members := range rbs {
// Removes any prefix before the role name ('roles/' or 'projects/<my-project>/roles/' for a custom role).
// Prepend 'custom_' if custom role.
// Replaces '.' with '_' and turns each character to lower case.
// E.g. roles/orgpolicy.policyViewer --> orgpolicy_policyviewer
// projects/<my-project>/roles/osLoginProjectGet_6afd --> custom_osloginprojectget_6afd
suffix := role
// Predefined roles, e.g. roles/orgpolicy.policyViewer.
if strings.HasPrefix(suffix, "roles/") {
suffix = strings.TrimPrefix(suffix, "roles/")
} else { // Custom roles, e.g. projects/<my-project>/roles/osLoginProjectGet_6afd.
segs := strings.Split(suffix, "/")
suffix = "custom_" + segs[len(segs)-1]
}
suffix = strings.ToLower(strings.Replace(suffix, ".", "_", -1))
data := map[string]interface{}{
// organizations/1234, folders/1234, projects/1234
"target": fmt.Sprintf("%ss/%s", root.Type, root.ID),
// Also prepend type and id in the policy name to make it unique across multiple policies for the same role.
"suffix": fmt.Sprintf("%s_%s_%s", root.Type, root.ID, suffix),
"role": role,
"members": members,
}
in := filepath.Join(templateDir, "forseti", "tf_based", "iam_allow_bindings.yaml")
out := filepath.Join(outputPath, outputFolder, fmt.Sprintf("iam_allow_bindings_%s.yaml", suffix))
if err := template.WriteFile(in, out, data); err != nil {
return err
}
}
}
return nil
}