-
Notifications
You must be signed in to change notification settings - Fork 223
Cloud HA strategy should automatically use PROXY support when available. #84
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9cef3ff
1b7b0ec
17f0a51
685478b
ae89da0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,7 @@ import ( | |
| "context" | ||
| "fmt" | ||
| "os" | ||
| "strconv" | ||
| "testing" | ||
| "time" | ||
|
|
||
|
|
@@ -157,6 +158,95 @@ func TestRouterServiceInternalEndpoints(t *testing.T) { | |
| } | ||
| } | ||
|
|
||
| func TestClusterProxyProtocol(t *testing.T) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this providing much more value than the unit test in this case? I'm trying to think of how we could make it more black-box either here or in Origin... like, is the feature really "source IP is preserved on supported cloud environments" (PROXY being an implementation detail)?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't want to block on it right now, just food for thought
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That makes sense - have to rebase anyway so will fix the test then. Probably in the next few days (too many tests + needle pricks today to be in a sane frame of mind to do this right now).
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Aah, we need a service to return back the header info. Plus there's already an extended test for router headers (in the origin repo) that checks the remote ip -- it is disabled currently - but will work to fix on it there.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm fine to leave this and refactor the tests later. I'd rather have this test than no test!
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That wasn't an indictment of the quality of the test 😁 |
||
| cl, ns, err := getClient() | ||
| if err != nil { | ||
| t.Fatal(err) | ||
| } | ||
|
|
||
| infraConfig := &configv1.Infrastructure{} | ||
| err = cl.Get(context.TODO(), types.NamespacedName{Name: "cluster"}, infraConfig) | ||
| if err != nil { | ||
| t.Fatalf("failed to get infrastructure config: %v", err) | ||
| } | ||
|
|
||
| if infraConfig.Status.Platform != configv1.AWSPlatform { | ||
| t.Skip("test skipped on non-aws platform") | ||
| return | ||
| } | ||
|
|
||
| ci := &ingressv1alpha1.ClusterIngress{} | ||
| err = wait.PollImmediate(1*time.Second, 10*time.Second, func() (bool, error) { | ||
| if err := cl.Get(context.TODO(), types.NamespacedName{Namespace: ns, Name: "default"}, ci); err != nil { | ||
| return false, nil | ||
| } | ||
| return true, nil | ||
| }) | ||
| if err != nil { | ||
| t.Fatalf("failed to get default ClusterIngress: %v", err) | ||
| } | ||
|
|
||
| // Wait for the router deployment to exist. | ||
| deployment := &appsv1.Deployment{} | ||
| err = wait.PollImmediate(1*time.Second, 10*time.Second, func() (bool, error) { | ||
| if err := cl.Get(context.TODO(), types.NamespacedName{Namespace: "openshift-ingress", Name: fmt.Sprintf("router-%s", ci.Name)}, deployment); err != nil { | ||
| return false, nil | ||
| } | ||
| return true, nil | ||
| }) | ||
| if err != nil { | ||
| t.Fatalf("failed to get default router deployment: %v", err) | ||
| } | ||
|
|
||
| // Ensure proxy protocol is enabled on the router deployment. | ||
| proxyProtocolEnabled := false | ||
| for _, v := range deployment.Spec.Template.Spec.Containers[0].Env { | ||
| if v.Name == "ROUTER_USE_PROXY_PROTOCOL" { | ||
| if val, err := strconv.ParseBool(v.Value); err == nil { | ||
| proxyProtocolEnabled = val | ||
| break | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if !proxyProtocolEnabled { | ||
| t.Fatalf("expected router deployment to enable the PROXY protocol") | ||
| } | ||
|
|
||
| // Wait for the internal router service to exist. | ||
| internalService := &corev1.Service{} | ||
| err = wait.PollImmediate(1*time.Second, 10*time.Second, func() (bool, error) { | ||
| if err := cl.Get(context.TODO(), types.NamespacedName{Namespace: "openshift-ingress", Name: fmt.Sprintf("router-internal-%s", ci.Name)}, internalService); err != nil { | ||
| return false, nil | ||
| } | ||
| return true, nil | ||
| }) | ||
| if err != nil { | ||
| t.Fatalf("failed to get internal router service: %v", err) | ||
| } | ||
|
|
||
| // TODO: Wait for interal router service selector bug to be fixed. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. #90 merged, so this TODO is stale, right?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah but as per a comment from @ironcladlou previously I was debating on whether to do it here (or do it in origin as there's already a header test that checks for the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you want to make a followup task in Jira for this test refactor we can merge using operator scoped tests in the interest of time. |
||
| // An alternative to test this would be to use an actual proxy protocol | ||
| // request to the internal router service. | ||
| // import "net" | ||
| // connection, err := net.Dial("tcp", internalService.Spec.ClusterIP) | ||
| // if err != nil { | ||
| // t.Fatalf("failed to connect to internal router service: %v", err) | ||
| // } | ||
| // defer connection.Close() | ||
|
|
||
| // req := []byte("LOCAL\r\nGET / HTTP/1.1\r\nHost: non.existent.test\r\n\r\n") | ||
| // req = []byte(fmt.Sprintf("PROXY TCP4 10.9.8.7 %s 54321 443\r\nGET / HTTP/1.1\r\nHost: non.existent.test\r\n\r\n", internalService.Spec.ClusterIP)) | ||
| // connection.Write(req) | ||
| // data := make([]byte, 4096) | ||
| // if _, err := connection.Read(data); err != nil { | ||
| // t.Fatalf("failed to read response from internal router service: %v", err) | ||
| // } else { | ||
| // check response is a http response 503. | ||
| // } | ||
|
|
||
| } | ||
|
|
||
| // TODO: Use manifest factory to build expectations | ||
| // TODO: Find a way to do this test without mutating the default ingress? | ||
| func TestClusterIngressUpdate(t *testing.T) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be worth importing
github.com/kubernetes/cloud-provider-aws/pkg/cloudprovider/providers/awsand usingaws.ServiceAnnotationLoadBalancerProxyProtocol?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just tried to use that but it causes dep errors. See: https://gist.github.com/ramr/1573ecb990fc42f3d3b8c4de36a8c81c