func mergeRoles()

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
}