-
Notifications
You must be signed in to change notification settings - Fork 25
Buffered backends fix #44
Changes from all commits
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 |
---|---|---|
|
@@ -7,6 +7,21 @@ function _M.get_backends_data() | |
return configuration_data:get("backends") | ||
end | ||
|
||
local function fetch_request_body() | ||
ngx.req.read_body() | ||
local backends = ngx.req.get_body_data() | ||
|
||
if not backends then | ||
-- request body might've been wrote to tmp file if body > client_body_buffer_size | ||
local file_name = ngx.req.get_body_file() | ||
local file = assert(io.open(file_name, "rb")) | ||
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. what does |
||
backends = file:read("*all") | ||
file:close() | ||
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. what happens any of this function calls fail? 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. lines 18, 19 should be safe.
And then since |
||
end | ||
|
||
return backends | ||
end | ||
|
||
function _M.call() | ||
if ngx.var.request_method ~= "POST" and ngx.var.request_method ~= "GET" then | ||
ngx.status = ngx.HTTP_BAD_REQUEST | ||
|
@@ -26,11 +41,16 @@ function _M.call() | |
return | ||
end | ||
|
||
ngx.req.read_body() | ||
local backends = fetch_request_body() | ||
if not backends then | ||
ngx.log(ngx.ERR, "dynamic-configuration: POST carries empty response body") | ||
ngx.status = ngx.HTTP_BAD_REQUEST | ||
return | ||
end | ||
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. This is a change of behaviour - i can not think of anything bad with it, but also don't see why it it necessary. Did you add it merely so that you can assert for absence of this logs in the e2e test? 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. The intention with this is to not update the config if the request_body is Understandably, if the balancer module cannot parse the backends data, then it doesn't sync the update - so the failure is somewhat limited, but I still think that the logging and 5xx response increases visibility here. |
||
|
||
local success, err = configuration_data:set("backends", ngx.req.get_body_data()) | ||
local success, err = configuration_data:set("backends", backends) | ||
if not success then | ||
ngx.log(ngx.ERR, "error while saving configuration: " .. tostring(err)) | ||
ngx.log(ngx.ERR, "dynamic-configuration: error updating configuration: " .. tostring(err)) | ||
ngx.status = ngx.HTTP_BAD_REQUEST | ||
return | ||
end | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,6 +39,8 @@ import ( | |
var _ = framework.IngressNginxDescribe("Dynamic Configuration", func() { | ||
f := framework.NewDefaultFramework("dynamic-configuration") | ||
|
||
var defaultNginxConfigMapData map[string]string = nil | ||
|
||
BeforeEach(func() { | ||
err := enableDynamicConfiguration(f.KubeClientSet) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
@@ -68,11 +70,20 @@ var _ = framework.IngressNginxDescribe("Dynamic Configuration", func() { | |
Expect(err).ToNot(HaveOccurred()) | ||
Expect(log).ToNot(ContainSubstring("could not dynamically reconfigure")) | ||
Expect(log).To(ContainSubstring("first sync of Nginx configuration")) | ||
|
||
if defaultNginxConfigMapData == nil { | ||
defaultNginxConfigMapData, err = f.GetNginxConfigMapData() | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(defaultNginxConfigMapData).NotTo(BeNil()) | ||
} | ||
}) | ||
|
||
AfterEach(func() { | ||
err := disableDynamicConfiguration(f.KubeClientSet) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
err = f.SetNginxConfigMapData(defaultNginxConfigMapData) | ||
Expect(err).NotTo(HaveOccurred()) | ||
}) | ||
|
||
Context("when only backends change", func() { | ||
|
@@ -111,6 +122,40 @@ var _ = framework.IngressNginxDescribe("Dynamic Configuration", func() { | |
Expect(restOfLogs).ToNot(ContainSubstring("first sync of Nginx configuration")) | ||
}) | ||
|
||
It("configuration module should read from temp file when request body > client_body_buffer_size", func() { | ||
resp, _, errs := gorequest.New(). | ||
Get(fmt.Sprintf("%s?id=endpoints_only_changes", f.NginxHTTPURL)). | ||
Set("Host", "foo.com"). | ||
End() | ||
Expect(len(errs)).Should(BeNumerically("==", 0)) | ||
Expect(resp.StatusCode).Should(Equal(http.StatusOK)) | ||
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. what's this for? we already assert that backend i s available at https://github.com/Shopify/ingress/pull/44/files#diff-8700c46a8379c603b5e41ccbaff6b71eR60 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 think you wanna send this request after updating the client max body size, to make sure we parsed request body correctly |
||
|
||
// Update client-body-buffer-size to 1 byte | ||
err := f.UpdateNginxConfigMapData("client-body-buffer-size", "8") | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
replicas := 2 | ||
err = framework.UpdateDeployment(f.KubeClientSet, f.Namespace.Name, "http-svc", replicas, | ||
func(deployment *appsv1beta1.Deployment) error { | ||
deployment.Spec.Replicas = framework.NewInt32(int32(replicas)) | ||
_, err := f.KubeClientSet.AppsV1beta1().Deployments(f.Namespace.Name).Update(deployment) | ||
return err | ||
}) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
time.Sleep(5 * time.Second) | ||
log, err := f.NginxLogs() | ||
|
||
Expect(err).ToNot(HaveOccurred()) | ||
Expect(log).ToNot(BeEmpty()) | ||
index := strings.Index(log, "id=endpoints_only_changes") | ||
restOfLogs := log[index:] | ||
|
||
By("POSTing new backends to Lua endpoint") | ||
Expect(restOfLogs).To(ContainSubstring("a client request body is buffered to a temporary file")) | ||
Expect(restOfLogs).ToNot(ContainSubstring("POST carries empty response body")) | ||
}) | ||
|
||
It("should handle annotation changes", func() { | ||
ingress, err := f.KubeClientSet.ExtensionsV1beta1().Ingresses(f.Namespace.Name).Get("foo.com", metav1.GetOptions{}) | ||
Expect(err).ToNot(HaveOccurred()) | ||
|
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
body
? since this is not backends specific