forked from kubernetes/kubernetes
-
Notifications
You must be signed in to change notification settings - Fork 102
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
UPSTREAM: <carry>: sets X-OpenShift-Internal-If-Not-Ready HTTP Header…
… for GC and Namespace controllers In general, setting the header will result in getting 429 when the server hasn't been ready. This prevents certain controllers like GC, Namespace from accidentally removing resources when the caches haven't been fully synchronized. OpenShift-Rebase-Source: 2ebf199
- Loading branch information
1 parent
580ebf6
commit 30deac4
Showing
5 changed files
with
111 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package app | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
"net/textproto" | ||
"testing" | ||
) | ||
|
||
func TestRejectIfNotReadyHeaderRT(t *testing.T) { | ||
scenarios := []struct { | ||
name string | ||
eligibleUsers []string | ||
currentUser string | ||
expectHeader bool | ||
}{ | ||
{ | ||
name: "scenario 1: happy path", | ||
currentUser: "system:serviceaccount:kube-system:generic-garbage-collector", | ||
eligibleUsers: []string{"generic-garbage-collector", "namespace-controller"}, | ||
expectHeader: true, | ||
}, | ||
{ | ||
name: "scenario 2: ineligible user", | ||
currentUser: "system:serviceaccount:kube-system:service-account-controller", | ||
eligibleUsers: []string{"generic-garbage-collector", "namespace-controller"}, | ||
expectHeader: false, | ||
}, | ||
} | ||
|
||
for _, scenario := range scenarios { | ||
t.Run(scenario.name, func(t *testing.T) { | ||
// set up the test | ||
fakeRT := fakeRTFunc(func(r *http.Request) (*http.Response, error) { | ||
// this is where we validate if the header was set or not | ||
headerSet := func() bool { | ||
if len(r.Header.Get("X-OpenShift-Internal-If-Not-Ready")) > 0 { | ||
return true | ||
} | ||
return false | ||
}() | ||
if scenario.expectHeader && !headerSet { | ||
return nil, fmt.Errorf("%v header wasn't set", textproto.CanonicalMIMEHeaderKey("X-OpenShift-Internal-If-Not-Ready")) | ||
} | ||
if !scenario.expectHeader && headerSet { | ||
return nil, fmt.Errorf("didn't expect %v header", textproto.CanonicalMIMEHeaderKey("X-OpenShift-Internal-If-Not-Ready")) | ||
} | ||
if scenario.expectHeader { | ||
if value := r.Header.Get("X-OpenShift-Internal-If-Not-Ready"); value != "reject" { | ||
return nil, fmt.Errorf("unexpected value %v in the %v header, expected \"reject\"", value, textproto.CanonicalMIMEHeaderKey("X-OpenShift-Internal-If-Not-Ready")) | ||
} | ||
} | ||
return nil, nil | ||
}) | ||
target := newRejectIfNotReadyHeaderRoundTripper(scenario.eligibleUsers)(fakeRT) | ||
req, err := http.NewRequest("GET", "", nil) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
req.Header.Set("User-Agent", scenario.currentUser) | ||
|
||
// act and validate | ||
if _, err := target.RoundTrip(req); err != nil { | ||
t.Fatal(err) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
type fakeRTFunc func(r *http.Request) (*http.Response, error) | ||
|
||
func (rt fakeRTFunc) RoundTrip(r *http.Request) (*http.Response, error) { | ||
return rt(r) | ||
} |