-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
HTTP plugin code 400 on connection to Citrix ADC #11478
Comments
Hi,
It does look like the system you are connecting to returns a 201, which will eventually require the fix in #11472. However, Telegraf is not getting that far and instead getting a 400 per your telegraf log. The Citrix ADC docs say the reason is in the body, so let's try to find out why. I have put up #11482, which should have some artifacts attached shortly. Can you give that a try and see what the body says? |
Hi, Same story with latest build (with more debug information this time):
Because of "Invalid payload format. Default format is json" I think we may need to see exactly what Telegraf is sending to Citrix ADC, to get to the root cause of the problem. |
Thanks for trying that out! We saw something similar in #11083 and learned that some devices are expected the content length and did not like a request formed by Go's NopCloser. Given this is for a request to generate a cookie, the request will not be huge, and there is no need to use the NopCloser. I have pushed an update to the PR that will change the body to use a io.Reader over an io.ReadCloser and also print out some debug information before doing the request. Can you give that update a shot once new artifacts are attached? |
I am not sure which artifact you are referring to. I tried this one: #11482 Anyway the result is following: Telegraf is not stopping, but I also don't see any data from the Citrix device in my InfluxDB instance (however I do get data from few test SNMP probes).
So far I didn't see any other connection attempts to Citrix in logs, so I assume that it authenticates successfully, but it is not sending any proper API calls to draw data. Now the situation is getting a bit more interesting when I set cookie_auth_renewal = "5m" I am getting inital session authentication, then Telegraf tries to renew the session with old session cookie (which I suppose it shouldn't as per the log):
|
It sounds like progress and indeed sounds like the Cirtix server was possibly expecting the content length similar to #11083.
Can you demonstrate a renewal with curl 1) with the cookie in the headers and 2) without the cookie in the headers, please? The 401 makes it pretty clear that the user credentials are wrong on renewal, so it seems unable to get a new cookie which is why the old cookie is used. |
Similar to influxdata#11083, some HTTP servers seem to quietly requires the content-length header in messages sent. Use of Go's ReadCloser does not allow for the content-length to be sent. As this is for a simple login the body length will be very small and the more efficient processing of a closer is not required in this use case. This also adds the ability to see the response body in the event of an error to gain a bit more details. fixes: influxdata#11478
Let me demonstrate 2)
I think there is no such process to go with 1) method. Citrix ADC API documentation says you can logout/terminate a session using a cookie, but to initiate new session it is required to send login and password without previous session cookie. Old session will just time-out on Citrix ADC at some point of time. In the example above Curl does use a cookie to initiate a session |
Thanks for the response. I've pushed another update just now that will omit the cookie from the headers during an auth. Once new artifacts build, can you give that one more shot? Thanks again! |
Similar story with the latest artifact, although there is no mention about cookie in the reply from Citrix ADC this time.
|
Hmm I re-added the debug info to print out the headers. Maybe it is getting set again? Can you try one more time? I am not sure what else this might be. Your CURL examples in your previous comment omitted the example of logging in with the cookie in the header. I wanted to see if you could reproduce the same failure on the CLI. |
Below is the flow you request. First is login, then regular API call, third request is a second authentication attempt.
|
thank you! That does show that setting the cookie is causing a 401. I just pushed another change which will recreate the cookie jar at every reauth. This should ensure the cookie is never used during the auth process. |
It looks better now. Session renewal is working. I see that because of those messages:
However I still don't see any real statistic data from Citrix ADC. |
Similar to influxdata#11083, some HTTP servers seem to quietly requires the content-length header in messages sent. Use of Go's ReadCloser does not allow for the content-length to be sent. As this is for a simple login the body length will be very small and the more efficient processing of a closer is not required in this use case. Moves the creation of the cookie jar as well. On a re-auth, the cookie was included in the request. Not only does this not make sense it can cause issues on some APIs where this was not expected. Given the original request does not contain this it seems safe to remake the cookie jar, emptying it, for each auth request. This also adds the ability to see the response body in the event of an error to gain a bit more details. fixes: influxdata#11478
Awesome! Thanks for hanging in there. I am going to get this branch merged since it already fixes a couple different issues.
Based on your previous messages you are getting JSON back that looks like: {
"errorcode": 0,
"message": "Done",
"severity": "NONE",
"lbvserver": [
{
"name": "lb-test-ssl",
"avgcltttlb": "0",
"cltresponsetimeapdex": 1,
"vsvrsurgecount": "0",
"establishedconn": "0",
"inactsvcs": "0",
"vslbhealth": "0",
"primaryipaddress": "169.254.1.1",
"primaryport": 443,
"type": "SSL",
"state": "DOWN",
"actsvcs": "0",
"cpuusagepm": "0",
"tothits": "0",
"hitsrate": 0,
"totalrequests": "0",
"requestsrate": 0,
"totalresponses": "0",
"responsesrate": 0,
"totalrequestbytes": "0",
"requestbytesrate": 0,
"totalresponsebytes": "0",
"responsebytesrate": 0,
"totalh2requests": "0",
"h2requestsrate": 0,
"totalh2responses": "0",
"h2responsesrate": 0,
"totalpktsrecvd": "0",
"pktsrecvdrate": 0,
"totalpktssent": "0",
"pktssentrate": 0,
"curclntconnections": "0",
"cursrvrconnections": "0",
"curpersistencesessions": "0",
"curbackuppersistencesessions": "0",
"surgecount": "0",
"svcsurgecount": "0",
"sothreshold": "0",
"totspillovers": "0",
"labelledconn": "0",
"pushlabel": "0",
"deferredreq": "0",
"deferredreqrate": 0,
"invalidrequestresponse": "0",
"invalidrequestresponsedropped": "0",
"totvserverdownbackuphits": "0",
"curmptcpsessions": "0",
"cursubflowconn": "0",
"totalconnreassemblyqueue75": "0",
"totalconnreassemblyqueueflush": "0",
"totalsvrbusyerr": "0",
"svrbusyerrrate": 0,
"reqretrycount": "0",
"reqretrycountexceeded": "0",
"httpmaxhdrszpkts": "0",
"httpmaxhdrfldlenpkts": "0",
"tcpmaxooopkts": "0",
"totcltttlbtransactions": "0",
"cltttlbtransactionsrate": 0,
"toleratingttlbtransactions": "0",
"toleratingttlbtransactionsrate": 0,
"frustratingttlbtransactions": "0",
"frustratingttlbtransactionsrate": 0
}
]
} As you are using the data_format = "json_v2"
[[inputs.http.json_v2]]
[[inputs.http.json_v2.object]]
path = "lbvserver" Which should produce something similar to this below. Note I used the file input to produce this example: file name="lb-test-ssl",avgcltttlb="0",cltresponsetimeapdex=1,vsvrsurgecount="0",establishedconn="0",inactsvcs="0",vslbhealth="0",primaryipaddress="169.254.1.1",primaryport=443,type="SSL",state="DOWN",actsvcs="0",cpuusagepm="0",tothits="0",hitsrate=0,totalrequests="0",requestsrate=0,totalresponses="0",responsesrate=0,totalrequestbytes="0",requestbytesrate=0,totalresponsebytes="0",responsebytesrate=0,totalh2requests="0",h2requestsrate=0,totalh2responses="0",h2responsesrate=0,totalpktsrecvd="0",pktsrecvdrate=0,totalpktssent="0",pktssentrate=0,curclntconnections="0",cursrvrconnections="0",curpersistencesessions="0",curbackuppersistencesessions="0",surgecount="0",svcsurgecount="0",sothreshold="0",totspillovers="0",labelledconn="0",pushlabel="0",deferredreq="0",deferredreqrate=0,invalidrequestresponse="0",invalidrequestresponsedropped="0",totvserverdownbackuphits="0",curmptcpsessions="0",cursubflowconn="0",totalconnreassemblyqueue75="0",totalconnreassemblyqueueflush="0",totalsvrbusyerr="0",svrbusyerrrate=0,reqretrycount="0",reqretrycountexceeded="0",httpmaxhdrszpkts="0",httpmaxhdrfldlenpkts="0",tcpmaxooopkts="0",totcltttlbtransactions="0",cltttlbtransactionsrate=0,toleratingttlbtransactions="0",toleratingttlbtransactionsrate=0,frustratingttlbtransactions="0",frustratingttlbtransactionsrate=0 1657891626000000000 From there you can continue to customize these settings further. |
I can confirm it is working. I finally get data in InfluxDB from Citrix ADC. Thank you for your help |
Relevant telegraf.conf
Logs from Telegraf
System info
Telegraf 1.22.4 (also tried 1.24.0~e945364b), Redhat 8.6
Docker
No response
Steps to reproduce
Expected behavior
I expect Telegraf HTTP plugin will connect to Citrix ADC and initiate the session, so I can draw stats using API calls
Moreover Telegraf stops on that error code 400, which in my humble opinion may be a bad design choice since it may crash otherwise a perfectly fine running Telegraf instance. Telegraf should just ignore the error and maybe retry later instead of stopping entirely. Imagine a situation where we have 1 HTTP endpoint and 99 SNMP devices. When we poll a device with HTTP plugin and it replies with non-200 code (because of some internal error), then whole Telegraf instance crashes and stops gathering statistics for those 99 perfectly working devices.
Actual behavior
E! [telegraf] Error running agent: could not initialize input inputs.http: cookie auth renewal received status code: 400 (Bad Request)
Additional info
When I use curl then it all works:
Establishing new session
curl -ik https://netscaler/nitro/v1/config/login -X POST -H 'Content-Type: application/json' -d '{ "login" :{"username": "username", "password": "password"}}'
HTTP/1.1 201 Created
Date: Fri, 08 Jul 2022 06:56:16 GMT
Server: Apache
X-Frame-Options: SAMEORIGIN
Set-Cookie: SESSID=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: sessionid=%23%23465611085B10AEECBC084499AA564FABA40BACAE435A343F2E40A96A12191918377A434FE2959F11C56076F0E08DDA840EFF0A9968DA9BAA0CA70555A6D168D5155CEBBAB02F9101FBED406B01164D0E617790FE785EF572F90C11FBDFE84FA7437466B824ECA2BC9652FB39FFCAF3DEF23B3AD421A53C32A8D52F75B874; path=/nitro/v1
Feature-Policy: camera 'none'; microphone 'none'; geolocation 'none'
Referrer-Policy: no-referrer
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Length: 328
Content-Type: application/json; charset=utf-8
{ "errorcode": 0, "message": "Done", "severity": "NONE", "sessionid": "##465611085B10AEECBC084499AA564FABA40BACAE435A343F2E40A96A12191918377A434FE2959F11C56076F0E08DDA840EFF0A9968DA9BAA0CA70555A6D168D5155CEBBAB02F9101FBED406B01164D0E617790FE785EF572F90C11FBDFE84FA7437466B824ECA2BC9652FB39FFCAF3DEF23B3AD421A53C32A8D52F75B874" }
Getting example statistics
curl -ik https://netscaler/nitro/v1/stat/lbvserver -H 'Content-Type: application/json' --cookie "sessionid=%23%23465611085B10AEECBC084499AA564FABA40BACAE435A343F2E40A96A12191918377A434FE2959F11C56076F0E08DDA840EFF0A9968DA9BAA0CA70555A6D168D5155CEBBAB02F9101FBED406B01164D0E617790FE785EF572F90C11FBDFE84FA7437466B824ECA2BC9652FB39FFCAF3DEF23B3AD421A53C32A8D52F75B874; path=/nitro/v1"
HTTP/1.1 200 OK
Date: Fri, 08 Jul 2022 06:57:05 GMT
Server: Apache
X-Frame-Options: SAMEORIGIN
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Feature-Policy: camera 'none'; microphone 'none'; geolocation 'none'
Referrer-Policy: no-referrer
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Length: 1640
Content-Type: application/json; charset=utf-8
{ "errorcode": 0, "message": "Done", "severity": "NONE", "lbvserver": [ { "name": "lb-test-ssl", "avgcltttlb": "0", "cltresponsetimeapdex": 1.000000, "vsvrsurgecount": "0", "establishedconn": "0", "inactsvcs": "0", "vslbhealth": "0", "primaryipaddress": "169.254.1.1", "primaryport": 443, "type": "SSL", "state": "DOWN", "actsvcs": "0", "cpuusagepm": "0", "tothits": "0", "hitsrate": 0, "totalrequests": "0", "requestsrate": 0, "totalresponses": "0", "responsesrate": 0, "totalrequestbytes": "0", "requestbytesrate": 0, "totalresponsebytes": "0", "responsebytesrate": 0, "totalh2requests": "0", "h2requestsrate": 0, "totalh2responses": "0", "h2responsesrate": 0, "totalpktsrecvd": "0", "pktsrecvdrate": 0, "totalpktssent": "0", "pktssentrate": 0, "curclntconnections": "0", "cursrvrconnections": "0", "curpersistencesessions": "0", "curbackuppersistencesessions": "0", "surgecount": "0", "svcsurgecount": "0", "sothreshold": "0", "totspillovers": "0", "labelledconn": "0", "pushlabel": "0", "deferredreq": "0", "deferredreqrate": 0, "invalidrequestresponse": "0", "invalidrequestresponsedropped": "0", "totvserverdownbackuphits": "0", "curmptcpsessions": "0", "cursubflowconn": "0", "totalconnreassemblyqueue75": "0", "totalconnreassemblyqueueflush": "0", "totalsvrbusyerr": "0", "svrbusyerrrate": 0, "reqretrycount": "0", "reqretrycountexceeded": "0", "httpmaxhdrszpkts": "0", "httpmaxhdrfldlenpkts": "0", "tcpmaxooopkts": "0", "totcltttlbtransactions": "0", "cltttlbtransactionsrate": 0, "toleratingttlbtransactions": "0", "toleratingttlbtransactionsrate": 0, "frustratingttlbtransactions": "0", "frustratingttlbtransactionsrate": 0 } ] }
At first I thought that maybe Telegraf just won't accept code 201 as per #11134
so I tested new build #11472
but it still fails
The text was updated successfully, but these errors were encountered: