CoreV1API_listPodForAllNamespaces/CoreV1API_listNamespacedPod API return 422 error
KagumiRA opened this issue · comments
Hello, I have problem when I try to run c/examples/list_pod/main.c , the program return
The return code of HTTP request=422
Cannot get any pod.
My k8s client version is "v1.28.2" and server version is "v1.28.2". Please help me debug these problems!
422 means that the body of the request is malformed.
My guess is that your cluster doesn't have a default
namespace, but that's a guess.
You should print the body of the response and you will get a more detailed error message.
422 means that the body of the request is malformed.
My guess is that your cluster doesn't have a
default
namespace, but that's a guess.You should print the body of the response and you will get a more detailed error message.
Thanks for helping me!! I try running the code under my cluster having default namespace and return same error. How can I print the body of the response? Where do the response exist?
it works using python, but when i use c language, i have the same error. i just change the namespace to my namespace.
pod_list = CoreV1API_listNamespacedPod(apiClient, "dialogue-dev",
NULL, /* pretty /
0, / allowWatchBookmarks /
NULL, / continue /
NULL, / fieldSelector /
NULL, / labelSelector /
0, / limit /
NULL, / resourceVersion /
NULL, / resourceVersionMatch /
0, / sendInitialEvents /
0, / timeoutSeconds /
0 / watch */
);
i only get the response_code 422, No additional information。
I can reproduce this issue.
Actually this problem also exists in GitHub Action, but we don't parse the return value 422 as an error.
The cause may be some integer type parameters. I'll check it out.
Maybe it helps:
#203
(gdb) p (char *)apiClient->dataReceived
$3 = 0x5555555b0250 "{\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"ListOptions.meta.k8s.io \\\"\\\" is invalid: sendInitialEvents: Forbidden: sendInitialEvents is forbidden for list\",\"reason\":\"Invalid\",\"details\":{\"group\":\"meta.k8s.io\",\"kind\":\"ListOptions\",\"causes\":[{\"reason\":\"FieldValueForbidden\",\"message\":\"Forbidden: sendInitialEvents is forbidden for list\",\"field\":\"sendInitialEvents\"}]},\"code\":422}\n"
The parameter sendInitialEvents
cannot be passed in the function CoreV1API_listNamespacedPod
whether set to 0 or 1.
So this issue cannot be fixed due to the current implementation of the C client.
If you want a workaround, please patch the code:
diff --git a/kubernetes/api/CoreV1API.c b/kubernetes/api/CoreV1API.c
index 53cb60a..ddd2fcd 100644
--- a/kubernetes/api/CoreV1API.c
+++ b/kubernetes/api/CoreV1API.c
@@ -22381,7 +22381,7 @@ CoreV1API_listNamespacedPod(apiClient_t *apiClient, char * _namespace , char * p
char *keyQuery_sendInitialEvents = NULL;
char * valueQuery_sendInitialEvents = NULL;
keyValuePair_t *keyPairQuery_sendInitialEvents = 0;
- if (1) // Always send boolean parameters to the API server
+ if (0) // Always ignore sendInitialEvents
{
keyQuery_sendInitialEvents = strdup("sendInitialEvents");
valueQuery_sendInitialEvents = calloc(1,MAX_NUMBER_LENGTH);
Thanks for helping me. I try to ignore sendInitialEvents, but it still returns 422. I try to print the apiClient->dataReceived in gdb, but it has nothing.
(gdb) p (char *)apiClient->dataReceived
$1 = 0x0
You have to add a breakpoint at this line:
b CoreV1API.c:22442
to debug the C client library and then print apiClient->dataReceived
i ignore sendInitialEvents, it works. thanks for help from ityuhui .
error:
Breakpoint 2, CoreV1API_listNamespacedPod (apiClient=0x555555586390, _namespace=0x555555556008 "dialogue-dev", pretty=0x0, allowWatchBookmarks=0, _continue=0x0, fieldSelector=0x0, labelSelector=0x0, limit=0, resourceVersion=0x0,
resourceVersionMatch=0x0, sendInitialEvents=0, timeoutSeconds=0, watch=0) at /root/k8s-study/c/kubernetes/api/CoreV1API.c:22442
22442 cJSON *CoreV1APIlocalVarJSON = cJSON_Parse(apiClient->dataReceived);
(gdb) n
22443 v1_pod_list_t *elementToReturn = v1_pod_list_parseFromJSON(CoreV1APIlocalVarJSON);
(gdb) p apiClient
$1 = (apiClient_t *) 0x555555586390
(gdb) p *apiClient
$2 = {basePath = 0x55555558ade0 "https://10.150.148.26:6443", sslConfig = 0x555555588090, dataReceived = 0x5555555b9ae0, dataReceivedLen = 412, data_callback_func = 0x0, progress_func = 0x0, progress_data = 0x0, response_code = 422,
apiKeys_BearerToken = 0x5555555700e0}
(gdb) p apiClient->dataReceived
$3 = (void *) 0x5555555b9ae0
(gdb) p *apiClient->dataReceived
Attempt to dereference a generic pointer.
(gdb) p (char *)apiClient->dataReceived
$4 = 0x5555555b9ae0 "{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"ListOptions.meta.k8s.io \"\" is invalid: sendInitialEvents: Forbidden: sendInitialEvents is forbidden for list","reason":"...
(gdb)
it seems all api need ignore sendInitialEvents(for example, CoreV1API_listNamespacedEndpoints)? Is there an official upgrade to address this issue?
Thanks for helping!
I try to print apiClient->dataReceived
after adding a breakpoint b CoreV1API.c:22442
with ignoring sendInitialEvents in CoreV1API.c:22381 and CoreV1API.c:20988.
I still get the same result:
(gdb) p (char*)apiClient->dataReceived
$2 = 0x555555669f10 "{\"kind\":\"Status\",\"apiVersion\":\"v1\",\"metadata\":{},\"status\":\"Failure\",\"message\":\"ListOptions.meta.k8s.io \\\"\\\" is invalid: sendInitialEvents: Forbidden: sendInitialEvents is forbidden for list\",\"reason\":\"Invalid\",\"details\":{\"group\":\"meta.k8s.io\",\"kind\":\"ListOptions\",\"causes\":[{\"reason\":\"FieldValueForbidden\",\"message\":\"Forbidden: sendInitialEvents is forbidden for list\",\"field\":\"sendInitialEvents\"}]},\"code\":422}\n"
At least, we know what problem lead to return 422 in my environment. How can I fix the problem? Thanks!
This problem (whether to send int/boolean type parameters to the API server when their value is 0
) has been around for a while and we need to find a solution to fix it.
I have some ideas:
Option 1: Add a flag sendXxx
for every int/boolean type parameter xxx
to control whether to send xxx
to the API server.
e.g.
v1_pod_list_t* CoreV1API_listPodForAllNamespaces(apiClient_t *apiClient,
int sendAllowWatchBookmarks, int allowWatchBookmarks,
char * _continue, char * fieldSelector, char * labelSelector,
int sendLimit, int limit,
char * pretty, char * resourceVersion, char * resourceVersionMatch,
int sendSendInitialEvents, int sendInitialEvents,
int sendTimeoutSeconds, int timeoutSeconds,
int sendWatch, int watch);
Option 2: Use int *foo
for the int/boolean type parameters, if foo == NULL
, ignore sending.
e.g.
v1_pod_list_t* CoreV1API_listPodForAllNamespaces(apiClient_t *apiClient,
int *pAllowWatchBookmarks,
char * _continue, char * fieldSelector, char * labelSelector,
int *pLimit,
char * pretty, char * resourceVersion, char * resourceVersionMatch,
int *pSendInitialEvents,
int *pTimeoutSeconds,
int *pWatch);
Option 3: Add a parameter alwaysSendIntParameter
in apiClient_t
if (apiClilent->alwaysSendIntParameter) {
always send int/boolean type parameters
} else {
send the int/boolean type parameters whose value is not `NULL/0`
}
Users need to set apiClilent->alwaysSendIntParameter
before calling the API such as CoreV1API_listPodForAllNamespaces
Hi @brendandburns
What do you think of these solutions ?
cc @wing328 @zhemant @michelealbano for early discussion as this change will eventually be made in OpenAPI-Generator/c-libcurl.
I would vote for either
typedef struct {
bool is_none,
int value
} optional_int_t;
or using int*
with NULL
meaning "don't send"
int*
is probably easier for clients to deal with the change.
I prefer int*
to solve this issue.
What do you think ? @wing328 @zhemant @michelealbano
I would say int *
and possibly similar for boolean/any other primitive which is not pointer. Then it is also easy to handle from code generator as it will possibly remove the need of individual type separation
I prefer int* to solve this issue.
Me too.
Thank you for your votes and suggestions !Based on the result of discussion, I'm going to implement the int*
solution.
So far, we have been discussing the case in the API function parameter list, but in fact the same problem exists with OpenAPI's model. The detail is in #193
In short, the int/boolean members/fields in a model should also be changed to int*
to support the required
check:
I'll make this the next phase of work once I resolve this issue.
I also prefer using int*. I am a little worried for all the heap fragmentation it will cause, but it's still the best option. Michele
…
On Wed, Nov 8, 2023 at 3:26 PM William Cheng @.> wrote: I prefer int to solve this issue. Me too. — Reply to this email directly, view it on GitHub <#209 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AC66LHCC5B6N6XU32P2YM6LYDOI7TAVCNFSM6AAAAAA6QQ25POVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQMBRHE4TKMRZGU . You are receiving this because you were mentioned.Message ID: @.*>
fwiw, it doesn't have to cause heap fragementation if people use &
to pass pointers to stack allocated variables when they make the client calls.
e.g.
int foo;
someApiCall(&foo);