Endpoint Awareness: Read backends data from tmp file as well

Actually read from the file

Logs probably shouldn't assume knowledge of implementation detail

Typos

Added integration test, and dynamic update config refactor

Don't force the 8k default

Minimal test case to make the configuration/backends request body write to temp file

Leverage new safe config updating methods, and use 2 replicas instead of 4

Small refactor

Better integration test, addresses other feedback

Update bindata
This commit is contained in:
Andrew Louis 2018-04-05 11:00:37 -04:00
parent 62895ffd0b
commit d3d383d1cc
3 changed files with 64 additions and 4 deletions

View file

@ -116,7 +116,7 @@ func etcNginxLuaBalancerLua() (*asset, error) {
return a, nil return a, nil
} }
var _etcNginxLuaConfigurationLua = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x93\xcd\x6e\xdb\x30\x10\x84\xef\x7a\x8a\xad\x4e\x32\xe0\xc8\xf7\x00\x3e\xa4\xb1\x9a\x02\xad\xed\xd4\x51\xce\x04\x23\xae\x25\xa2\xec\xd2\x59\x2e\x93\x1a\x45\xfb\xec\x85\x7e\x62\x44\x89\xd0\x26\x27\x03\x34\x67\xbf\x99\xd1\xf2\xec\x0c\xa4\xb1\x01\x6c\x00\x69\x10\xbe\x46\x0d\x8c\x07\xc6\x80\x24\x5a\xac\x27\xf0\x7b\xb8\xf4\xb4\xb7\x75\xe4\xfe\x20\x08\xc7\x4a\xc0\x12\x58\x12\x64\xd2\x6e\x61\xa9\x66\x0c\x61\x21\xc7\x03\x86\xbc\xf6\x89\xf3\x95\x76\x50\x3d\xd7\x29\xa3\x45\xc3\x12\xa8\xfe\x99\x87\x46\x33\x9a\xfc\xf5\xff\xc9\xa0\x54\x6b\x58\xc2\xaf\xdf\x49\xb2\x8f\x54\x75\x54\xb5\xce\x6b\x14\x75\xa7\xab\xef\x48\x26\x74\xb7\xb3\x59\x02\xc0\x28\x91\x69\x82\x75\x5e\xa3\x64\xe9\x93\x20\x9d\x25\x48\x66\x3c\xb0\xd2\xce\x75\x33\xec\xbe\xb3\xf5\xa0\x39\x67\xbc\x8f\x18\x44\xfd\x40\x69\xbc\x81\x3f\x4b\x48\xaf\xb7\x37\x65\x0a\x9a\xcc\xbf\x2e\x5d\x15\x65\xda\x56\x48\x09\x00\xf4\x21\x45\x4b\x0c\x43\xe2\xcf\x65\x79\xad\x3e\x5e\xac\xd4\xae\xf8\x76\x5b\xdc\x94\xa7\x5b\x07\xb6\x24\x59\xba\x25\x77\x84\x16\xd4\x71\xae\x8a\x12\x06\x46\x00\xcd\x08\xda\x39\xff\x88\xe6\x43\x3a\xeb\x84\x7d\xe6\x04\xa0\x8b\x34\xe9\x3f\xb2\xed\x7c\x2d\x46\xc5\x2c\x4e\x75\xfc\xcf\xeb\x66\x5b\xaa\x4f\xdb\xdb\xcd\xea\xa5\xd3\x8d\x17\xd8\xfb\x48\xef\x31\x33\xf4\xb4\x7c\x63\x4f\xdb\x2f\x2f\xa0\xd3\x1f\x7f\x1a\xdf\xaa\x18\xef\x73\x46\x6d\xd4\x9d\x37\xc7\x6c\xd6\x1e\xf7\x7b\x15\x62\x55\x61\x08\x73\x40\x66\x58\x4e\x2d\x4d\x18\x2d\xcd\xfc\x34\xae\xe3\x7b\x73\x7c\xc6\x6e\x83\x7a\x79\x9a\x39\x0e\xe5\x7c\x9d\xb5\xbf\xc5\x6e\x37\x87\x14\x99\x3d\xc3\x63\x63\x1d\x42\xd0\x0f\x96\xea\x31\xfa\x1c\x52\xc8\x73\x10\x1f\x84\x2d\xd5\x19\x32\x0f\xe9\xde\xb6\x48\x53\x1d\xbc\x56\x5d\xee\x8a\x8b\xb2\x58\xf5\xef\x60\x78\x36\x6a\x9d\xfc\x0d\x00\x00\xff\xff\x7b\xd0\x2f\xb3\x03\x04\x00\x00") var _etcNginxLuaConfigurationLua = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x54\xd1\x6e\xdb\x3a\x0c\x7d\xf7\x57\xf0\xfa\xe5\xba\x17\x89\xf3\x5e\x20\x17\xe8\x5a\xaf\x03\xb6\x36\x5d\xea\x3e\x1b\x8a\x4d\xdb\xc2\x14\x2a\x95\xe8\xb6\xd9\xb0\x7d\xfb\x20\x59\x76\x93\xce\xd8\xba\xed\x29\xb1\x74\x48\x9e\x73\x48\x6a\x3e\x07\x6e\xa5\x05\x69\x81\x5b\x84\x0f\x9d\x00\x83\x3b\x83\x16\x89\x05\x4b\x4d\xa0\x6b\x38\xd7\x54\xcb\xa6\x33\xfd\x81\x65\xd3\x95\x0c\x92\x40\x12\xa3\x21\xa1\x16\x92\x1a\x83\xd6\x2e\x78\xbf\x43\x9b\x36\x3a\x52\xba\x14\x0a\xca\xc3\xb8\xa2\x12\x2c\x60\x09\xd4\x3c\xa5\xb6\x15\x06\xab\xf4\xc7\xfb\x28\x44\x16\x57\xb0\x84\x2f\x5f\xa3\xa8\xee\xa8\xf4\x55\x8b\xab\xb4\x41\x2e\x36\xa2\xfc\x84\x54\x59\x8f\x4e\x4e\x22\x00\x83\xdc\x19\x9a\xa8\x75\xda\x20\x27\xf1\x10\x10\x9f\x44\x48\xd5\x90\x7f\x4c\x5b\x23\x97\x6d\x61\xf0\xbe\x43\xcb\xc5\x46\x57\x7b\x9f\xd4\x91\x34\x78\x9f\x1a\x14\xd5\xf3\x69\x1f\xeb\x3e\x83\x0e\x07\xf1\xac\x74\xb5\x1f\x18\x45\x00\xb2\x06\xd2\xdc\x03\xb9\x45\x8a\x00\x00\xe6\x73\x08\x65\xfa\x8b\xad\x6c\x5a\xfe\xf7\x01\x61\x83\x48\xf0\x68\x24\x33\x12\xb0\x06\xde\xee\xa0\x96\x0a\x5d\x1a\x8f\xfc\x1f\x4a\x25\x91\x42\x99\x4d\x57\xd7\x68\x0a\x2b\x3f\xa3\xcf\x1b\x04\x49\x85\x05\x89\x2d\x4e\x31\x73\x97\x5e\xc0\x21\x1a\x96\x20\x75\xaa\x77\x48\xc9\x18\x3c\x83\xd8\x6c\x62\xaf\x61\x54\xe1\xb1\xa3\x8a\xd1\x6f\x92\xca\x1f\x78\x53\xdd\x9f\x60\x8b\x83\x9f\x3a\xdb\x92\xf8\x3f\xa1\x54\xdc\x97\xf5\xa7\xa5\xd2\xb6\xe7\x11\x82\x42\x2a\x17\xd9\x37\xe7\xb0\xdb\xa5\x50\xca\x83\x1d\x8f\xe6\x29\x7d\x10\x26\x1d\xfa\xb4\x45\x6e\x75\x05\xdf\x96\x10\xdf\xac\x6e\xf3\x18\x04\x55\x3f\x03\x5d\x66\x79\xfc\xac\xc1\x4f\x20\x0b\xee\x6c\x30\xeb\x5d\x9e\xdf\x14\x6f\xce\x2e\x8a\x75\xf6\xf1\x2e\xbb\xcd\x47\xd4\xce\x48\xe2\x24\x5e\x91\xda\x83\x2b\xe4\xeb\x5c\x66\xf9\xd0\x49\x0b\xc2\x20\x08\xa5\xf4\x23\x56\xff\x04\xad\xbd\xaa\x67\x95\x13\xfc\x3b\x23\x3d\xaf\xc5\xd1\xd4\x2e\xc6\x59\xfd\x15\xd7\xeb\x55\x5e\xbc\x5d\xdd\x5d\x5f\xbc\x64\x7a\xed\x1a\xa6\x3b\xfa\x1d\x32\xc1\xa7\xe5\x2b\x7d\x5a\xbd\x7f\x51\x74\x7a\x33\xa7\xcb\x87\x0d\x0a\x50\x37\x2e\xd3\xfb\x37\x6c\xd0\x00\x3c\xe2\xa4\x74\x93\xb8\xdf\x6c\xbd\x9e\x41\x5c\xed\x49\x6c\x65\x39\x3f\xb2\xf2\x14\x3a\x12\x1b\x37\xb8\x1a\xdc\x30\xc2\x83\x50\xb2\x3a\x5a\xc0\x60\xd0\xeb\x86\x61\x5a\x87\xed\xca\x12\xad\x9d\x01\x1a\x03\xcb\xa9\x27\xc8\x1e\x3d\x41\xb3\x51\xd0\x81\xc6\x90\xe4\x0f\x24\xa2\x31\xda\x40\xb7\xab\x04\x4b\x6a\xe0\xc5\x6d\x0c\x69\x0a\xac\x2d\x1b\x49\x4d\x82\xc6\x9c\xfc\x8d\xe0\xe9\xa8\xf3\x75\x76\x96\x67\x17\xfd\xf2\x86\x6d\x2e\xae\xa2\xef\x01\x00\x00\xff\xff\x63\xb9\xf8\x38\x55\x06\x00\x00")
func etcNginxLuaConfigurationLuaBytes() ([]byte, error) { func etcNginxLuaConfigurationLuaBytes() ([]byte, error) {
return bindataRead( return bindataRead(

View file

@ -7,6 +7,26 @@ function _M.get_backends_data()
return configuration_data:get("backends") return configuration_data:get("backends")
end end
local function fetch_request_body()
ngx.req.read_body()
local body = ngx.req.get_body_data()
if not body then
-- request body might've been written to tmp file if body > client_body_buffer_size
local file_name = ngx.req.get_body_file()
local file = io.open(file_name, "rb")
if not file then
return nil
end
body = file:read("*all")
file:close()
end
return body
end
function _M.call() function _M.call()
if ngx.var.request_method ~= "POST" and ngx.var.request_method ~= "GET" then if ngx.var.request_method ~= "POST" and ngx.var.request_method ~= "GET" then
ngx.status = ngx.HTTP_BAD_REQUEST ngx.status = ngx.HTTP_BAD_REQUEST
@ -26,11 +46,16 @@ function _M.call()
return return
end end
ngx.req.read_body() local backends = fetch_request_body()
if not backends then
ngx.log(ngx.ERR, "dynamic-configuration: unable to read valid request body")
ngx.status = ngx.HTTP_BAD_REQUEST
return
end
local success, err = configuration_data:set("backends", ngx.req.get_body_data()) local success, err = configuration_data:set("backends", backends)
if not success then 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 ngx.status = ngx.HTTP_BAD_REQUEST
return return
end end

View file

@ -104,6 +104,41 @@ var _ = framework.IngressNginxDescribe("Dynamic Configuration", func() {
Expect(restOfLogs).ToNot(ContainSubstring("first sync of Nginx configuration")) Expect(restOfLogs).ToNot(ContainSubstring("first sync of Nginx configuration"))
}) })
It("should be able to update endpoints even when the update POST size(request body) > size(client_body_buffer_size)", func() {
// Update client-body-buffer-size to 1 byte
err := f.UpdateNginxConfigMapData("client-body-buffer-size", "1")
Expect(err).NotTo(HaveOccurred())
replicas := 0
err = framework.UpdateDeployment(f.KubeClientSet, f.IngressController.Namespace, "http-svc", replicas, nil)
Expect(err).NotTo(HaveOccurred())
replicas = 4
err = framework.UpdateDeployment(f.KubeClientSet, f.IngressController.Namespace, "http-svc", replicas, nil)
Expect(err).NotTo(HaveOccurred())
time.Sleep(5 * time.Second)
resp, _, errs := gorequest.New().
Get(f.IngressController.HTTPURL).
Set("Host", "foo.com").
End()
Expect(len(errs)).Should(BeNumerically("==", 0))
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
log, err := f.NginxLogs()
Expect(err).ToNot(HaveOccurred())
Expect(log).ToNot(BeEmpty())
index := strings.Index(log, "POST /configuration/backends HTTP/1.1")
restOfLogs := log[index:]
Expect(err).ToNot(HaveOccurred())
Expect(log).ToNot(BeEmpty())
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("dynamic-configuration: unable to read valid request body"))
})
It("should handle annotation changes", func() { It("should handle annotation changes", func() {
ingress, err := f.KubeClientSet.ExtensionsV1beta1().Ingresses(f.IngressController.Namespace).Get("foo.com", metav1.GetOptions{}) ingress, err := f.KubeClientSet.ExtensionsV1beta1().Ingresses(f.IngressController.Namespace).Get("foo.com", metav1.GetOptions{})
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())