From 3f6419e9e04ddb48ee1dd6334704b69a6c93600c Mon Sep 17 00:00:00 2001 From: Brendan Burns Date: Fri, 14 Aug 2020 12:24:40 -0700 Subject: [PATCH] Add delete/create/replace to the generic client. --- examples/Makefile | 2 + examples/generic/main.c | 21 +++++++ kubernetes/CMakeLists.txt | 1 + kubernetes/include/generic.h | 19 +++++- kubernetes/src/generic.c | 108 ++++++++++++++++++++++++++--------- 5 files changed, 124 insertions(+), 27 deletions(-) diff --git a/examples/Makefile b/examples/Makefile index 6cb5afe..f50bfbe 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -3,9 +3,11 @@ all: cd list_pod; make cd list_pod_incluster; make cd exec_provider; make + cd generic; make clean: cd create_pod; make clean cd list_pod; make clean cd list_pod_incluster; make clean cd exec_provider; make clean + cd generic; make clean diff --git a/examples/generic/main.c b/examples/generic/main.c index 0f3cb2a..9570346 100644 --- a/examples/generic/main.c +++ b/examples/generic/main.c @@ -33,6 +33,27 @@ int main(int argc, char *argv[]) genericClient_free(genericClient); genericClient = NULL; + + genericClient = genericClient_create(apiClient, "", "v1", "namespaces"); + + const char *body = "{\"apiVersion\": \"v1\", \"kind\": \"Namespace\", \"metadata\": { \"name\": \"test\" } }"; + char *create = Generic_createResource(genericClient, body); + printf("%s\n", create); + free(create); + + const char *updateBody = "{\"apiVersion\": \"v1\", \"kind\": \"Namespace\", \"metadata\": { \"name\": \"test\", \"labels\": { \"foo\": \"bar\" } } }"; + char *update = Generic_replaceResource(genericClient, "test", updateBody); + printf("%s\n", update); + free(update); + + char *del = Generic_deleteResource(genericClient, "test"); + printf("%s\n", del); + free(del); + + genericClient_free(genericClient); + genericClient = NULL; + + apiClient_free(apiClient); apiClient = NULL; free_client_config(basePath, sslConfig, apiKeys); diff --git a/kubernetes/CMakeLists.txt b/kubernetes/CMakeLists.txt index 7c53bcd..d869610 100644 --- a/kubernetes/CMakeLists.txt +++ b/kubernetes/CMakeLists.txt @@ -800,6 +800,7 @@ set(HDRS include/list.h include/binary.h include/keyValuePair.h + include/generic.h external/cJSON.h model/object.h model/admissionregistration_v1_service_reference.h diff --git a/kubernetes/include/generic.h b/kubernetes/include/generic.h index 15dc645..46e054d 100644 --- a/kubernetes/include/generic.h +++ b/kubernetes/include/generic.h @@ -3,6 +3,10 @@ #include "../include/apiClient.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef struct genericClient_t { apiClient_t *client; char *apiGroup; @@ -19,4 +23,17 @@ char* Generic_readResource(genericClient_t *client, const char *name); char* Generic_listNamespaced(genericClient_t *client, const char *ns); char* Generic_list(genericClient_t *client); -#endif \ No newline at end of file +char* Generic_deleteNamespacedResource(genericClient_t *client, const char *ns, const char *name); +char* Generic_deleteResource(genericClient_t *client, const char* name); + +char* Generic_createNamespacedResource(genericClient_t *client, const char *ns, const char* body); +char* Generic_createResource(genericClient_t *client, const char* body); + +char* Generic_replaceNamespacedResource(genericClient_t *client, const char *ns, const char *name, const char* body); +char* Generic_replaceResource(genericClient_t *client, const char *name, const char* body); + +#ifdef __cplusplus +} +#endif + +#endif // __GENERIC_H__ \ No newline at end of file diff --git a/kubernetes/src/generic.c b/kubernetes/src/generic.c index 5db950b..ff699cd 100644 --- a/kubernetes/src/generic.c +++ b/kubernetes/src/generic.c @@ -19,30 +19,39 @@ void genericClient_free(genericClient_t* client) { } void makeNamespacedResourcePath(char* path, genericClient_t *client, const char* namespace, const char* name) { - snprintf( - path, 128, - "/apis/%s/%s/namespaces/%s/%s/%s", - client->apiGroup, - client->apiVersion, - namespace, - client->resourcePlural, - name - ); + if (!client->apiGroup || strlen(client->apiGroup) == 0) { + snprintf(path, 128, "/api/%s/namespaces/%s/%s/%s", + client->apiVersion, namespace, client->resourcePlural, name); + } else { + snprintf( + path, 128, + "/apis/%s/%s/namespaces/%s/%s/%s", + client->apiGroup, + client->apiVersion, + namespace, + client->resourcePlural, + name + ); + } } void makeResourcePath(char* path, genericClient_t *client, const char* name) { - snprintf( - path, 128, - "/apis/%s/%s/%s/%s", - client->apiGroup, - client->apiVersion, - client->resourcePlural, - name - ); + if (!client->apiGroup || strlen(client->apiGroup) == 0) { + snprintf(path, 128, "/api/%s/%s/%s", client->apiVersion, client->resourcePlural, name); + } else { + snprintf( + path, 128, + "/apis/%s/%s/%s/%s", + client->apiGroup, + client->apiVersion, + client->resourcePlural, + name + ); + } } -char* readInternal(genericClient_t *client, const char* path) { - apiClient_invoke(client->client, path, NULL, NULL, NULL, NULL, NULL, NULL, "GET"); +char* callInternal(genericClient_t *client, const char* path, const char* method, const char* body) { + apiClient_invoke(client->client, path, NULL, NULL, NULL, NULL, NULL, body, method); if (client->client->response_code == 200) { printf("%s\n","OK"); @@ -66,26 +75,73 @@ char* Generic_readNamespacedResource(genericClient_t *client, const char *namesp char path[128]; makeNamespacedResourcePath(path, client, namespace, name); - return readInternal(client, path); + return callInternal(client, path, "GET", NULL); } char* Generic_readResource(genericClient_t *client, const char *name) { char path[128]; makeResourcePath(path, client, name); - return readInternal(client, path); + return callInternal(client, path, "GET", NULL); } char *Generic_listNamespaced(genericClient_t *client, const char *namespace) { char path[128]; - snprintf(path, 128, "/apis/%s/%s/namespaces/%s/%s", - client->apiGroup, client->apiVersion, namespace, client->resourcePlural); - readInternal(client, path); + if (client->apiGroup) { + snprintf(path, 128, "/apis/%s/%s/namespaces/%s/%s", + client->apiGroup, client->apiVersion, namespace, client->resourcePlural); + } else { + snprintf(path, 128, "/api/%s/namespaces/%s/%s", + client->apiVersion, namespace, client->resourcePlural); + } + return callInternal(client, path, "GET", NULL); } char *Generic_list(genericClient_t *client) { char path[128]; - snprintf(path, 128, "/apis/%s/%s", client->apiGroup, client->apiVersion, client->resourcePlural); - readInternal(client, path); + if (client->apiGroup) { + snprintf(path, 128, "/apis/%s/%s/%s", + client->apiGroup, client->apiVersion, client->resourcePlural); + } else { + snprintf(path, 128, "/api/%s/%s", + client->apiVersion, client->resourcePlural); + } + return callInternal(client, path, "GET", NULL); } +char* Generic_deleteNamespacedResource(genericClient_t *client, const char *namespace, const char *name) { + char path[128]; + makeNamespacedResourcePath(path, client, namespace, name); + return callInternal(client, path, "DELETE", NULL); +} + +char* Generic_deleteResource(genericClient_t *client, const char* name) { + char path[128]; + makeResourcePath(path, client, name); + return callInternal(client, path, "DELETE", NULL); +} + +char* Generic_createNamespacedResource(genericClient_t *client, const char *ns, const char* body) { + char path[128]; + makeNamespacedResourcePath(path, client, ns, ""); + return callInternal(client, path, "POST", body); +} + +char* Generic_createResource(genericClient_t *client, const char* body) { + char path[128]; + makeResourcePath(path, client, ""); + printf("%s\n", path); + return callInternal(client, path, "POST", body); +} + +char* Generic_replaceNamespacedResource(genericClient_t *client, const char *ns, const char *name, const char* body) { + char path[128]; + makeNamespacedResourcePath(path, client, ns, name); + return callInternal(client, path, "PUT", body); +} + +char* Generic_replaceResource(genericClient_t *client, const char *name, const char* body) { + char path[128]; + makeResourcePath(path, client, name); + return callInternal(client, path, "PUT", body); +}