func generateIAMPolicies()

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
}