/* Build a set of openstack objects for each project (tenant) that we have access to. Retuns the list of creds and both ID->project and project->ID maps We build a new map each time, copying existing references, so that if a parallel thread has a copy and is working from it a change to the map isn't disruptive. This function also sets a reference ("_ref_") entry in the map which can be used to pull an entry out when any of them will do. NOTE: All errors will be logged, but only the first error will be returned to the caller. */ func refresh_creds(admin *ostack.Ostack, old_list map[string]*ostack.Ostack, id2pname map[string]*string) (creds map[string]*ostack.Ostack, gerr error) { var ( err error ) creds = make(map[string]*ostack.Ostack) // new map to fill in if old_list == nil { old_list = creds } for k, v := range id2pname { // run the list of projects and add creds to the map if we don't have them if old_list[*v] == nil { osif_sheep.Baa(1, "adding creds for: %s/%s", k, *v) creds[*v], err = admin.Dup(v) // duplicate creds for this project and then authorise to get a token if err != nil { osif_sheep.Baa(1, "WRN: unable to authorise credentials for project: %s [TGUOSI008]", *v) delete(creds, *v) } if gerr == nil { // ensure error captured for return if last in list is good gerr = err } } else { creds[*v] = old_list[*v] // reuse the data osif_sheep.Baa(2, "reusing credentials for: %s", *v) } if creds["_ref"] == nil && creds[*v] != nil { // set the quick reference key creds["_ref_"] = creds[*v] } } return }