Skip to content

Commit dc38fbd

Browse files
Merge pull request #585 from gcs278/OCPBUGS-26498-upgradeable-status-4.15
[release-4.15] OCPBUGS-28928: Upgrade Validation plugin for SHA1 certs
2 parents 4b6be4d + fa20a24 commit dc38fbd

26 files changed

+2151
-296
lines changed

.gitleaks.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[allowlist]
2+
description = "Global Allowlist"
3+
4+
# Ignore based on any subset of the file path
5+
paths = [
6+
# Ignore all example certs used for testing
7+
'''pkg\/router\/routeapihelpers\/validation_test.go$''',
8+
'''pkg\/router\/template\/plugin_test.go$''',
9+
'''pkg\/router\/template\/router_test.go$''',
10+
]
11+

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ require (
1111
github.com/gocarina/gocsv v0.0.0-20190927101021-3ecffd272576
1212
github.com/google/go-cmp v0.5.9
1313
github.com/haproxytech/config-parser/v4 v4.0.0-rc1
14-
github.com/openshift/api v0.0.0-20230807132801-600991d550ac
14+
github.com/openshift/api v0.0.0-20240522145529-93d6bda14341
1515
github.com/openshift/client-go v0.0.0-20230120202327-72f107311084
1616
github.com/openshift/library-go v0.0.0-20230120202744-256994f916c4
1717
github.com/prometheus/client_golang v1.16.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
245245
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
246246
github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE=
247247
github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
248-
github.com/openshift/api v0.0.0-20230807132801-600991d550ac h1:HqT8MmYGXiUGUW0BjygTGOOvqO2wIsTaG3q8nboJyPY=
249-
github.com/openshift/api v0.0.0-20230807132801-600991d550ac/go.mod h1:yimSGmjsI+XF1mr+AKBs2//fSXIOhhetHGbMlBEfXbs=
248+
github.com/openshift/api v0.0.0-20240522145529-93d6bda14341 h1:JQpzgk+p24rkgNbNsrNR0yLm63WTKapuT60INU5BqT8=
249+
github.com/openshift/api v0.0.0-20240522145529-93d6bda14341/go.mod h1:qNtV0315F+f8ld52TLtPvrfivZpdimOzTi3kn9IVbtU=
250250
github.com/openshift/client-go v0.0.0-20230120202327-72f107311084 h1:66uaqNwA+qYyQDwsMWUfjjau8ezmg1dzCqub13KZOcE=
251251
github.com/openshift/client-go v0.0.0-20230120202327-72f107311084/go.mod h1:M3h9m001PWac3eAudGG3isUud6yBjr5XpzLYLLTlHKo=
252252
github.com/openshift/library-go v0.0.0-20230120202744-256994f916c4 h1:cFYg18OROQMHlrGWL9HpV1elDKbnRFLz/ED5VvP3qvw=

pkg/cmd/infra/router/router.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ type RouterSelection struct {
6868

6969
ExtendedValidation bool
7070

71+
UpgradeValidation bool
72+
73+
UpgradeValidationForceAddCondition bool
74+
UpgradeValidationForceRemoveCondition bool
75+
7176
ListenAddr string
7277

7378
// WatchEndpoints when true will watch Endpoints instead of
@@ -94,7 +99,10 @@ func (o *RouterSelection) Bind(flag *pflag.FlagSet) {
9499
flag.StringSliceVar(&o.AllowedDomains, "allowed-domains", envVarAsStrings("ROUTER_ALLOWED_DOMAINS", "", ","), "List of comma separated domains to allow in routes. If specified, only the domains in this list will be allowed routes. Note that domains in the denied list take precedence over the ones in the allowed list")
95100
flag.BoolVar(&o.AllowWildcardRoutes, "allow-wildcard-routes", isTrue(env("ROUTER_ALLOW_WILDCARD_ROUTES", "")), "Allow wildcard host names for routes")
96101
flag.BoolVar(&o.DisableNamespaceOwnershipCheck, "disable-namespace-ownership-check", isTrue(env("ROUTER_DISABLE_NAMESPACE_OWNERSHIP_CHECK", "")), "Disables the namespace ownership checks for a route host with different paths or for overlapping host names in the case of wildcard routes. Please be aware that if namespace ownership checks are disabled, routes in a different namespace can use this mechanism to 'steal' sub-paths for existing domains. This is only safe if route creation privileges are restricted, or if all the users can be trusted.")
97-
flag.BoolVar(&o.ExtendedValidation, "extended-validation", isTrue(env("EXTENDED_VALIDATION", "true")), "If set, then an additional extended validation step is performed on all routes admitted in by this router. Defaults to true and enables the extended validation checks.")
102+
flag.BoolVar(&o.ExtendedValidation, "extended-validation", isTrue(env("EXTENDED_VALIDATION", "true")), "If set, then an additional extended validation step is performed on all routes processed by this router. Defaults to true and enables the extended validation checks.")
103+
flag.BoolVar(&o.UpgradeValidation, "upgrade-validation", isTrue(env("UPGRADE_VALIDATION", "true")), "If set, then an additional upgrade validation step is performed on all routes processed by this router. Defaults to true and enables the upgrade validation checks.")
104+
flag.BoolVar(&o.UpgradeValidationForceAddCondition, "debug-upgrade-validation-force-add-condition", isTrue(env("DEBUG_UPGRADE_VALIDATION_FORCE_ADD_CONDITION", "")), "If set, then the upgrade validation plugin will forcibly add the UnservableInFutureVersions condition. For testing purposes only.")
105+
flag.BoolVar(&o.UpgradeValidationForceRemoveCondition, "debug-upgrade-validation-force-remove-condition", isTrue(env("DEBUG_UPGRADE_VALIDATION_FORCE_REMOVE_CONDITION", "")), "If set, then the upgrade validation plugin will forcibly remove the UnservableInFutureVersions condition. For testing purposes only.")
98106
flag.Bool("enable-ingress", false, "Enable configuration via ingress resources.")
99107
flag.MarkDeprecated("enable-ingress", "Ingress resources are now synchronized to routes automatically.")
100108
flag.StringVar(&o.ListenAddr, "listen-addr", env("ROUTER_LISTEN_ADDR", ""), "The name of an interface to listen on to expose metrics and health checking. If not specified, will not listen. Overrides stats port.")

pkg/cmd/infra/router/template.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -785,7 +785,7 @@ func (o *TemplateRouterOptions) Run(stopCh <-chan struct{}) error {
785785
factory.RouteModifierFn = o.RouteUpdate
786786

787787
var plugin router.Plugin = templatePlugin
788-
var recorder controller.RejectionRecorder = controller.LogRejections
788+
var recorder controller.RouteStatusRecorder = controller.LogRejections
789789
if o.UpdateStatus {
790790
lease := writerlease.New(time.Minute, 3*time.Second)
791791
go lease.Run(stopCh)
@@ -798,6 +798,9 @@ func (o *TemplateRouterOptions) Run(stopCh <-chan struct{}) error {
798798
recorder = status
799799
plugin = status
800800
}
801+
if o.UpgradeValidation {
802+
plugin = controller.NewUpgradeValidation(plugin, recorder, o.UpgradeValidationForceAddCondition, o.UpgradeValidationForceRemoveCondition)
803+
}
801804
if o.ExtendedValidation {
802805
plugin = controller.NewExtendedValidator(plugin, recorder)
803806
}

pkg/router/controller/contention.go

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ import (
77
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
88
"k8s.io/client-go/tools/cache"
99

10-
"github.com/google/go-cmp/cmp"
11-
"github.com/google/go-cmp/cmp/cmpopts"
12-
1310
routev1 "github.com/openshift/api/route/v1"
1411
)
1512

@@ -24,14 +21,15 @@ type ContentionTracker interface {
2421
// expected state of the object at this time and may be used by the tracker to
2522
// determine if the most recent update was a contention. This method does not
2623
// update the state of the tracker.
27-
IsChangeContended(id string, now time.Time, current *routev1.RouteIngress) bool
24+
IsChangeContended(id contentionKey, now time.Time, current *routev1.RouteIngress) bool
2825
// Clear informs the tracker that the provided ingress state was confirmed to
2926
// match the current state of this process. If a subsequent call to IsChangeContended
3027
// is made within the expiration window, the object will be considered as contended.
31-
Clear(id string, current *routev1.RouteIngress)
28+
Clear(id contentionKey, current *routev1.RouteIngress)
3229
}
3330

3431
type elementState int
32+
type contentionKey string
3533

3634
const (
3735
stateCandidate elementState = iota
@@ -57,7 +55,7 @@ type SimpleContentionTracker struct {
5755

5856
lock sync.Mutex
5957
contentions int
60-
ids map[string]trackerElement
58+
ids map[contentionKey]trackerElement
6159
}
6260

6361
// NewSimpleContentionTracker creates a ContentionTracker that will prevent writing
@@ -74,7 +72,7 @@ func NewSimpleContentionTracker(informer cache.SharedInformer, routerName string
7472
expires: interval,
7573
maxContentions: 5,
7674

77-
ids: make(map[string]trackerElement),
75+
ids: make(map[contentionKey]trackerElement),
7876
}
7977
}
8078

@@ -104,7 +102,7 @@ func (t *SimpleContentionTracker) Run(stopCh <-chan struct{}) {
104102
return
105103
}
106104
if ingress := ingressChanged(oldRoute, route, t.routerName); ingress != nil {
107-
t.Changed(string(route.UID), ingress)
105+
t.Changed(contentionKey(route.UID), ingress)
108106
}
109107
},
110108
})
@@ -160,7 +158,7 @@ func (t *SimpleContentionTracker) flush() {
160158
// a separate goroutine and may have seen newer events than the current route controller
161159
// plugins, so we don't do direct time comparisons. Instead we count edge transitions on
162160
// a given id.
163-
func (t *SimpleContentionTracker) Changed(id string, current *routev1.RouteIngress) {
161+
func (t *SimpleContentionTracker) Changed(id contentionKey, current *routev1.RouteIngress) {
164162
t.lock.Lock()
165163
defer t.lock.Unlock()
166164

@@ -207,7 +205,7 @@ func (t *SimpleContentionTracker) Changed(id string, current *routev1.RouteIngre
207205
}
208206
}
209207

210-
func (t *SimpleContentionTracker) IsChangeContended(id string, now time.Time, current *routev1.RouteIngress) bool {
208+
func (t *SimpleContentionTracker) IsChangeContended(id contentionKey, now time.Time, current *routev1.RouteIngress) bool {
211209
t.lock.Lock()
212210
defer t.lock.Unlock()
213211

@@ -232,7 +230,7 @@ func (t *SimpleContentionTracker) IsChangeContended(id string, now time.Time, cu
232230
return false
233231
}
234232

235-
func (t *SimpleContentionTracker) Clear(id string, current *routev1.RouteIngress) {
233+
func (t *SimpleContentionTracker) Clear(id contentionKey, current *routev1.RouteIngress) {
236234
t.lock.Lock()
237235
defer t.lock.Unlock()
238236

@@ -245,11 +243,48 @@ func (t *SimpleContentionTracker) Clear(id string, current *routev1.RouteIngress
245243
t.ids[id] = last
246244
}
247245

246+
// ingressEqual compares two route ingresses and returns a bool if they are equivalent.
248247
func ingressEqual(a, b *routev1.RouteIngress) bool {
249-
// In addition to the RouteIngress' string fields, compare the available admission condition to determine
250-
// if the given ingress' are equal. See https://bugzilla.redhat.com/show_bug.cgi?id=1908389.
251-
return a.Host == b.Host && a.RouterCanonicalHostname == b.RouterCanonicalHostname && a.WildcardPolicy == b.WildcardPolicy && a.RouterName == b.RouterName &&
252-
cmp.Equal(findCondition(a, routev1.RouteAdmitted), findCondition(b, routev1.RouteAdmitted), cmpopts.IgnoreFields(routev1.RouteIngressCondition{}, "LastTransitionTime"))
248+
// In addition to the RouteIngress' string fields, compare all conditions to determine
249+
// if the given ingress' are equal.
250+
return a.Host == b.Host &&
251+
a.RouterCanonicalHostname == b.RouterCanonicalHostname &&
252+
a.WildcardPolicy == b.WildcardPolicy &&
253+
a.RouterName == b.RouterName &&
254+
ingressConditionsEqual(a.Conditions, b.Conditions)
255+
}
256+
257+
// ingressConditionsEqual determines if the route ingress conditions are equal,
258+
// while ignoring LastTransitionTime.
259+
func ingressConditionsEqual(a, b []routev1.RouteIngressCondition) bool {
260+
if len(a) != len(b) {
261+
return false
262+
}
263+
264+
// Compare each condition in a with every condition in b.
265+
// Given the current max of only two conditions, nested loops are more efficient than sorting.
266+
for i := 0; i < len(a); i++ {
267+
matchFound := false
268+
for j := 0; j < len(b); j++ {
269+
if conditionsEqual(&a[i], &b[j]) {
270+
matchFound = true
271+
break
272+
}
273+
}
274+
if !matchFound {
275+
return false
276+
}
277+
}
278+
279+
return true
280+
}
281+
282+
// conditionsEqual compares two RouteIngressConditions, ignoring LastTransitionTime.
283+
func conditionsEqual(a, b *routev1.RouteIngressCondition) bool {
284+
return a.Type == b.Type &&
285+
a.Status == b.Status &&
286+
a.Reason == b.Reason &&
287+
a.Message == b.Message
253288
}
254289

255290
func ingressConditionTouched(ingress *routev1.RouteIngress) *metav1.Time {

pkg/router/controller/extended_validator.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ type ExtendedValidator struct {
1919
// plugin is the next plugin in the chain.
2020
plugin router.Plugin
2121

22-
// recorder is an interface for indicating route rejections.
23-
recorder RejectionRecorder
22+
// recorder is an interface for indicating route status.
23+
recorder RouteStatusRecorder
2424
}
2525

2626
// NewExtendedValidator creates a plugin wrapper that ensures only routes that
2727
// pass extended validation are relayed to the next plugin in the chain.
28-
// Recorder is an interface for indicating why a route was rejected.
29-
func NewExtendedValidator(plugin router.Plugin, recorder RejectionRecorder) *ExtendedValidator {
28+
// Recorder is an interface for indicating route status updates.
29+
func NewExtendedValidator(plugin router.Plugin, recorder RouteStatusRecorder) *ExtendedValidator {
3030
return &ExtendedValidator{
3131
plugin: plugin,
3232
recorder: recorder,
@@ -45,6 +45,7 @@ func (p *ExtendedValidator) HandleEndpoints(eventType watch.EventType, endpoints
4545

4646
// HandleRoute processes watch events on the Route resource.
4747
func (p *ExtendedValidator) HandleRoute(eventType watch.EventType, route *routev1.Route) error {
48+
log.V(10).Info("HandleRoute: ExtendedValidator")
4849
// Check if previously seen route and its Spec is unchanged.
4950
routeName := routeNameKey(route)
5051
if err := routeapihelpers.ExtendedValidateRoute(route).ToAggregate(); err != nil {

pkg/router/controller/host_admitter.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ type HostAdmitter struct {
7878
admitter RouteAdmissionFunc
7979

8080
// recorder is an interface for indicating route rejections.
81-
recorder RejectionRecorder
81+
recorder RouteStatusRecorder
8282

8383
// allowWildcardRoutes enables wildcard route support.
8484
allowWildcardRoutes bool
@@ -98,8 +98,8 @@ type HostAdmitter struct {
9898

9999
// NewHostAdmitter creates a plugin wrapper that checks whether or not to
100100
// admit routes and relay them to the next plugin in the chain.
101-
// Recorder is an interface for indicating why a route was rejected.
102-
func NewHostAdmitter(plugin router.Plugin, fn RouteAdmissionFunc, allowWildcards, disableNamespaceCheck bool, recorder RejectionRecorder) *HostAdmitter {
101+
// Recorder is an interface for indicating route status updates..
102+
func NewHostAdmitter(plugin router.Plugin, fn RouteAdmissionFunc, allowWildcards, disableNamespaceCheck bool, recorder RouteStatusRecorder) *HostAdmitter {
103103
return &HostAdmitter{
104104
plugin: plugin,
105105
admitter: fn,
@@ -126,6 +126,7 @@ func (p *HostAdmitter) HandleEndpoints(eventType watch.EventType, endpoints *kap
126126

127127
// HandleRoute processes watch events on the Route resource.
128128
func (p *HostAdmitter) HandleRoute(eventType watch.EventType, route *routev1.Route) error {
129+
log.V(10).Info("HandleRoute: HostAdmitter")
129130
if p.allowedNamespaces != nil && !p.allowedNamespaces.Has(route.Namespace) {
130131
// Ignore routes we don't need to "service" due to namespace
131132
// restrictions (ala for sharding).

pkg/router/controller/host_admitter_test.go

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,28 @@ const (
2222
BlockedTestDomain = "domain.blocked.test"
2323
)
2424

25-
type rejectionRecorder struct {
26-
rejections map[string]string
25+
type routeStatusRecorder struct {
26+
rejections map[string]string
27+
unservableInFutureVersions map[string]string
2728
}
2829

29-
func (_ rejectionRecorder) rejectionKey(route *routev1.Route) string {
30+
func (_ routeStatusRecorder) rejectionKey(route *routev1.Route) string {
3031
return route.Namespace + "-" + route.Name
3132
}
3233

33-
func (r rejectionRecorder) RecordRouteRejection(route *routev1.Route, reason, message string) {
34+
func (r routeStatusRecorder) RecordRouteRejection(route *routev1.Route, reason, message string) {
3435
r.rejections[r.rejectionKey(route)] = reason
3536
}
3637

37-
func (r rejectionRecorder) Clear() {
38+
func (r routeStatusRecorder) RecordRouteUnservableInFutureVersionsClear(route *routev1.Route) {
39+
delete(r.unservableInFutureVersions, r.rejectionKey(route))
40+
}
41+
42+
func (r routeStatusRecorder) RecordRouteUnservableInFutureVersions(route *routev1.Route, reason, message string) {
43+
r.unservableInFutureVersions[r.rejectionKey(route)] = reason
44+
}
45+
46+
func (r routeStatusRecorder) Clear() {
3847
r.rejections = make(map[string]string)
3948
}
4049

@@ -248,7 +257,7 @@ func TestWildcardHostDeny(t *testing.T) {
248257
func TestWildcardSubDomainOwnership(t *testing.T) {
249258
p := &fakePlugin{}
250259

251-
recorder := rejectionRecorder{rejections: make(map[string]string)}
260+
recorder := routeStatusRecorder{rejections: make(map[string]string)}
252261
admitter := NewHostAdmitter(p, wildcardAdmitter, true, false, recorder)
253262

254263
oldest := metav1.Time{Time: time.Now()}
@@ -505,7 +514,7 @@ func TestValidRouteAdmissionFuzzing(t *testing.T) {
505514
p := &fakePlugin{}
506515

507516
admitAll := func(route *routev1.Route) error { return nil }
508-
recorder := rejectionRecorder{rejections: make(map[string]string)}
517+
recorder := routeStatusRecorder{rejections: make(map[string]string)}
509518
admitter := NewHostAdmitter(p, RouteAdmissionFunc(admitAll), true, false, recorder)
510519

511520
oldest := metav1.Time{Time: time.Now()}
@@ -602,7 +611,7 @@ func TestInvalidRouteAdmissionFuzzing(t *testing.T) {
602611
p := &fakePlugin{}
603612

604613
admitAll := func(route *routev1.Route) error { return nil }
605-
recorder := rejectionRecorder{rejections: make(map[string]string)}
614+
recorder := routeStatusRecorder{rejections: make(map[string]string)}
606615
admitter := NewHostAdmitter(p, RouteAdmissionFunc(admitAll), true, false, recorder)
607616

608617
oldest := metav1.Time{Time: time.Now()}
@@ -787,7 +796,7 @@ func TestStatusWildcardPolicyNoOp(t *testing.T) {
787796
touched := metav1.Time{Time: now.Add(-time.Minute)}
788797
p := &fakePlugin{}
789798
c := fake.NewSimpleClientset()
790-
recorder := rejectionRecorder{rejections: make(map[string]string)}
799+
recorder := routeStatusRecorder{rejections: make(map[string]string)}
791800
admitter := NewHostAdmitter(p, wildcardAdmitter, true, false, recorder)
792801
err := admitter.HandleRoute(watch.Added, &routev1.Route{
793802
ObjectMeta: metav1.ObjectMeta{Name: "wild", Namespace: "thing", UID: types.UID("uid8")},
@@ -825,7 +834,7 @@ func TestStatusWildcardPolicyNotAllowedNoOp(t *testing.T) {
825834
touched := metav1.Time{Time: now.Add(-time.Minute)}
826835
p := &fakePlugin{}
827836
c := fake.NewSimpleClientset()
828-
recorder := rejectionRecorder{rejections: make(map[string]string)}
837+
recorder := routeStatusRecorder{rejections: make(map[string]string)}
829838
admitter := NewHostAdmitter(p, wildcardAdmitter, false, false, recorder)
830839
err := admitter.HandleRoute(watch.Added, &routev1.Route{
831840
ObjectMeta: metav1.ObjectMeta{Name: "wild", Namespace: "thing", UID: types.UID("uid8")},
@@ -862,7 +871,7 @@ func TestDisableOwnershipChecksFuzzing(t *testing.T) {
862871
p := &fakePlugin{}
863872

864873
admitAll := func(route *routev1.Route) error { return nil }
865-
recorder := rejectionRecorder{rejections: make(map[string]string)}
874+
recorder := routeStatusRecorder{rejections: make(map[string]string)}
866875
uniqueHostPlugin := NewUniqueHost(p, true, recorder)
867876
admitter := NewHostAdmitter(uniqueHostPlugin, RouteAdmissionFunc(admitAll), true, true, recorder)
868877

@@ -1026,7 +1035,7 @@ func TestDisableOwnershipChecksFuzzing(t *testing.T) {
10261035

10271036
func TestHandleNamespaceProcessing(t *testing.T) {
10281037
p := &fakePlugin{}
1029-
recorder := rejectionRecorder{rejections: make(map[string]string)}
1038+
recorder := routeStatusRecorder{rejections: make(map[string]string)}
10301039
admitter := NewHostAdmitter(p, wildcardAdmitter, true, false, recorder)
10311040

10321041
// Set namespaces handled in the host admitter plugin, the fakePlugin in
@@ -1148,7 +1157,7 @@ func TestHandleNamespaceProcessing(t *testing.T) {
11481157
func TestWildcardPathRoutesWithoutNSCheckResyncs(t *testing.T) {
11491158
p := &fakePlugin{}
11501159

1151-
recorder := rejectionRecorder{rejections: make(map[string]string)}
1160+
recorder := routeStatusRecorder{rejections: make(map[string]string)}
11521161
admitter := NewHostAdmitter(p, wildcardAdmitter, true, true, recorder)
11531162

11541163
oldest := metav1.Time{Time: time.Now()}

0 commit comments

Comments
 (0)