in internal/pkg/policy/policy_output.go [396:472]
func mergeRoles(zlog zerolog.Logger, old, new *RoleT) (*RoleT, error) {
if old == nil {
return new, nil
}
if new == nil {
return old, nil
}
oldMap, err := smap.Parse(old.Raw)
if err != nil {
return nil, err
}
if oldMap == nil {
return new, nil
}
newMap, err := smap.Parse(new.Raw)
if err != nil {
return nil, err
}
if newMap == nil {
return old, nil
}
destMap := smap.Map{}
// copy all from new
for k, v := range newMap {
destMap[k] = v
}
findNewKey := func(m smap.Map, candidate string) string {
if strings.HasSuffix(candidate, "-rdstale") {
candidate = strings.TrimSuffix(candidate, "-rdstale")
dashIdx := strings.LastIndex(candidate, "-")
if dashIdx >= 0 {
candidate = candidate[:dashIdx]
}
}
// 1 should be enough, 100 is just to have some space
for i := 0; i < 100; i++ {
c := fmt.Sprintf("%s-%d-rdstale", candidate, i)
if _, exists := m[c]; !exists {
return c
}
}
return ""
}
// copy old
for k, v := range oldMap {
newKey := findNewKey(destMap, k)
if newKey == "" {
zlog.Warn().Msg("Failed to find a key for role assignement.")
zlog.Debug().
RawJSON("roles", new.Raw).
Str("candidate", k).
Msg("roles not included.")
continue
}
destMap[newKey] = v
}
r := &RoleT{}
if r.Sha2, err = destMap.Hash(); err != nil {
return nil, err
}
if r.Raw, err = json.Marshal(destMap); err != nil {
return nil, err
}
return r, nil
}