in internal/policygen/iam.go [186:226]
func bindings(rn runner.Runner, resources []*states.Resource, rootType, idField string) (map[root]roleBindings, error) {
var bindings = make(map[root]roleBindings)
resourceType := fmt.Sprintf("google_%s_iam_binding", rootType) // authoritative for a given role
instances, err := terraform.GetInstancesForType(resources, resourceType)
if err != nil {
return nil, fmt.Errorf("get resource instances for type %q: %v", resourceType, err)
}
for _, ins := range instances {
if err := validateMandatoryStringFields(ins, []string{idField, "role"}); err != nil {
return nil, err
}
if err := validateMandatoryStringLists(ins, []string{"members"}); err != nil {
return nil, err
}
id, err := normalizeID(rn, rootType, ins[idField].(string)) // Type checked in validate function.
if err != nil {
return nil, fmt.Errorf("normalize root resource ID: %v", err)
}
key := root{Type: rootType, ID: id}
// Init the roleBindings map if it didn't exist.
if _, ok := bindings[key]; !ok {
bindings[key] = make(roleBindings)
}
role := ins["role"].(string)
var members []string
for _, s := range ins["members"].([]interface{}) {
members = append(members, s.(string)) // Type checked in validate function.
}
// There should not be more than one instance of google_%s_iam_binding for the same resource
// across all states. But we append all members just in case.
bindings[key][role] = append(bindings[key][role], members...)
}
return bindings, nil
}