GroupRemoveSuffix = GroupSpecialSeparator + "remove"
)
-// Keep in sync with sync_info.go:infoGroupDetectedRegexp
+// Keep in sync with cmd/safcm/sync_info.go:infoGroupDetectedRegexp
var groupNameRegexp = regexp.MustCompile(`^[a-z0-9_-]+$`)
func LoadGroups(cfg *Config, hosts *Hosts) (map[string][]string, error) {
"%s conflict with pre-defined group %q",
errPrefix, name)
}
- if hosts.Map[name] != nil {
+ if hosts.Map[name] != nil ||
+ hosts.Map[strings.TrimSuffix(name,
+ GroupRemoveSuffix)] != nil {
return nil, fmt.Errorf(
"%s conflict with existing host",
errPrefix)
if x == GroupAll {
continue
}
+ // Don't validate against groupNameRegexp because
+ // hosts have less strict restrictions.
if strings.Contains(x, GroupSpecialSeparator) {
return nil, fmt.Errorf(
"%s member %q must not contain %q",
if hosts.Map[x] != nil || groups[x] != nil {
continue
}
- return nil, fmt.Errorf("%s group %q not found",
+ return nil, fmt.Errorf("%s member %q not found",
errPrefix, x)
}
}
// Sanity check for global configuration
- for _, x := range cfg.GroupOrder {
- const errPrefix = "config.yaml: group_order:"
+ for _, x := range cfg.GroupPriority {
+ const errPrefix = "config.yaml: group_priority:"
if x == GroupAll {
continue
sort.Strings(res)
return res, nil
}
+
+// TransitivelyDetectedGroups returns all groups which depend on "detected"
+// groups, either directly or by depending on groups which transitively depend
+// on "detected" groups.
+func TransitivelyDetectedGroups(groups map[string][]string) []string {
+ work := make(map[string][]string)
+ for k, v := range groups {
+ work[k] = v
+ }
+
+ // Mark all groups which contain "detected" groups as long as new
+ // (transitive) "detected" groups are found.
+ detected := make(map[string]bool)
+ for {
+ change := false
+ for group, members := range work {
+ for _, x := range members {
+ if !detected[x] && !strings.HasPrefix(x,
+ GroupDetectedPrefix) {
+ continue
+ }
+ detected[strings.TrimSuffix(group,
+ GroupRemoveSuffix)] = true
+ delete(work, group)
+ change = true
+ }
+ }
+ if !change {
+ break
+ }
+ }
+
+ var res []string
+ for x := range detected {
+ res = append(res, x)
+ }
+ sort.Strings(res)
+ return res
+}