func bindings()

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
}