consolidateAutomationPolicies combines automation policies that are the same, for a cleaner overall output.
(aps []*caddytls.AutomationPolicy)
| 967 | // consolidateAutomationPolicies combines automation policies that are the same, |
| 968 | // for a cleaner overall output. |
| 969 | func consolidateAutomationPolicies(aps []*caddytls.AutomationPolicy) []*caddytls.AutomationPolicy { |
| 970 | // sort from most specific to least specific; we depend on this ordering |
| 971 | sort.SliceStable(aps, func(i, j int) bool { |
| 972 | if automationPolicyIsSubset(aps[i], aps[j]) { |
| 973 | return true |
| 974 | } |
| 975 | if automationPolicyIsSubset(aps[j], aps[i]) { |
| 976 | return false |
| 977 | } |
| 978 | return len(aps[i].SubjectsRaw) > len(aps[j].SubjectsRaw) |
| 979 | }) |
| 980 | |
| 981 | emptyAPCount := 0 |
| 982 | origLenAPs := len(aps) |
| 983 | // compute the number of empty policies (disregarding subjects) - see #4128 |
| 984 | // while we're at it, |
| 985 | emptyAP := new(caddytls.AutomationPolicy) |
| 986 | for i := 0; i < len(aps); i++ { |
| 987 | emptyAP.SubjectsRaw = aps[i].SubjectsRaw |
| 988 | emptyAP.ManagersRaw = nil |
| 989 | if reflect.DeepEqual(aps[i], emptyAP) { |
| 990 | // AP is empty |
| 991 | emptyAPCount++ |
| 992 | |
| 993 | // see if this AP shadows something later |
| 994 | shadowIdx := automationPolicyShadows(i, aps) |
| 995 | emptyAP.SubjectsRaw = nil |
| 996 | if shadowIdx >= 0 { |
| 997 | emptyAP.SubjectsRaw = aps[shadowIdx].SubjectsRaw |
| 998 | // allow the later policy, which is likely for a wildcard, to have cert |
| 999 | // managers ("get_certificate"), since wildcards now cover specific |
| 1000 | // subdomains by default, when configured (see discussion in #7559) |
| 1001 | emptyAP.ManagersRaw = aps[shadowIdx].ManagersRaw |
| 1002 | } |
| 1003 | |
| 1004 | // if this is the last AP, we can delete it, since auto-https should |
| 1005 | // pick it up; if it shadows something later that is also empty, we |
| 1006 | // can similarly delete this; but if it shadows something that is NOT |
| 1007 | // empty, we must not delete it since the shadowing has a purpose |
| 1008 | if i == len(aps)-1 || (shadowIdx >= 0 && reflect.DeepEqual(aps[shadowIdx], emptyAP)) { |
| 1009 | aps = slices.Delete(aps, i, i+1) |
| 1010 | i-- |
| 1011 | } |
| 1012 | } |
| 1013 | } |
| 1014 | // If all policies are empty, we can return nil, as there is no need to set any policy |
| 1015 | if emptyAPCount == origLenAPs { |
| 1016 | return nil |
| 1017 | } |
| 1018 | |
| 1019 | // remove or combine duplicate policies |
| 1020 | outer: |
| 1021 | for i := 0; i < len(aps); i++ { |
| 1022 | // compare only with next policies; we sorted by specificity so we must not delete earlier policies |
| 1023 | for j := i + 1; j < len(aps); j++ { |
| 1024 | // if they're exactly equal in every way, just keep one of them |
| 1025 | if reflect.DeepEqual(aps[i], aps[j]) { |
| 1026 | aps = slices.Delete(aps, j, j+1) |
no test coverage detected