From 1d79e0f4f6b98f97f47233c8720b6f63d65a1d43 Mon Sep 17 00:00:00 2001 From: DanyT Date: Fri, 5 Jul 2024 09:25:16 +0300 Subject: [PATCH] add example for load_kube_config_buffer --- examples/Makefile | 3 + .../list_pod_by_exec_provider.c~ | 71 +++++++++ examples/exec_provider/my_exec_provider.c~ | 44 ++++++ examples/list_pod_buffer/.gitignore | 1 + examples/list_pod_buffer/CMakeLists.txt | 4 + examples/list_pod_buffer/Makefile | 17 +++ examples/list_pod_buffer/main.c | 141 ++++++++++++++++++ 7 files changed, 281 insertions(+) create mode 100644 examples/exec_provider/list_pod_by_exec_provider.c~ create mode 100644 examples/exec_provider/my_exec_provider.c~ create mode 100644 examples/list_pod_buffer/.gitignore create mode 100644 examples/list_pod_buffer/CMakeLists.txt create mode 100644 examples/list_pod_buffer/Makefile create mode 100644 examples/list_pod_buffer/main.c diff --git a/examples/Makefile b/examples/Makefile index 65fcf94..b2c6eef 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -2,6 +2,7 @@ all: cd create_pod; make cd list_pod_with_invalid_kubeconfig; make cd list_pod; make + cd list_pod_buffer; make cd list_pod_incluster; make cd delete_pod; make cd exec_provider; make @@ -18,6 +19,7 @@ clean: cd create_pod; make clean cd list_pod_with_invalid_kubeconfig; make clean cd list_pod; make clean + cd list_pod_buffer; make clean cd list_pod_incluster; make clean cd delete_pod; make clean cd exec_provider; make clean @@ -35,6 +37,7 @@ test: kubectl wait --for=condition=ready --all pod -n default --timeout=60s cd list_pod_with_invalid_kubeconfig; make test cd list_pod; make test + cd list_pod_buffer; make test cd delete_pod; make test kubectl wait --for=delete pod/test-pod-6 -n default --timeout=120s cd list_secret; make test diff --git a/examples/exec_provider/list_pod_by_exec_provider.c~ b/examples/exec_provider/list_pod_by_exec_provider.c~ new file mode 100644 index 0000000..721b2a0 --- /dev/null +++ b/examples/exec_provider/list_pod_by_exec_provider.c~ @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include +#include + +void list_pod(apiClient_t * apiClient) +{ + v1_pod_list_t *pod_list = NULL; + pod_list = CoreV1API_listNamespacedPod(apiClient, "default", /*namespace */ + NULL, /* pretty */ + NULL, /* allowWatchBookmarks */ + NULL, /* continue */ + NULL, /* fieldSelector */ + NULL, /* labelSelector */ + NULL, /* limit */ + NULL, /* resourceVersion */ + NULL, /* resourceVersionMatch */ + NULL, /* sendInitialEvents */ + NULL, /* timeoutSeconds */ + NULL /* watch */ + ); + printf("The return code of HTTP request=%ld\n", apiClient->response_code); + if (pod_list) { + printf("Get pod list:\n"); + listEntry_t *listEntry = NULL; + v1_pod_t *pod = NULL; + list_ForEach(listEntry, pod_list->items) { + pod = listEntry->data; + printf("\tThe pod name: %s\n", pod->metadata->name); + } + v1_pod_list_free(pod_list); + pod_list = NULL; + } else { + printf("Cannot get any pod.\n"); + } +} + +int main(int argc, char *argv[]) +{ + int rc = 0; + + char *baseName = NULL; + sslConfig_t *sslConfig = NULL; + list_t *apiKeys = NULL; + apiClient_t *k8sApiClient = NULL; + + rc = load_kube_config(&baseName, &sslConfig, &apiKeys, "./config_with_exec_provider"); + if (0 == rc) { + k8sApiClient = apiClient_create_with_base_path(baseName, sslConfig, apiKeys); + } else { + printf("Cannot load kubernetes configuration.\n"); + return -1; + } + + if (k8sApiClient) { + list_pod(k8sApiClient); + } + + free_client_config(baseName, sslConfig, apiKeys); + baseName = NULL; + sslConfig = NULL; + apiKeys = NULL; + + apiClient_free(k8sApiClient); + k8sApiClient = NULL; + apiClient_unsetupGlobalEnv(); + + return rc; +} diff --git a/examples/exec_provider/my_exec_provider.c~ b/examples/exec_provider/my_exec_provider.c~ new file mode 100644 index 0000000..b0d4844 --- /dev/null +++ b/examples/exec_provider/my_exec_provider.c~ @@ -0,0 +1,44 @@ +#define _GNU_SOURCE +#include +#include +#include + +#define ENV_EXEC_CLIENT_CERTIFICATE_DATA "exec_client_certificate_data" +#define ENV_EXEC_CLIENT_PRIVATE_KEY "exec_client_private_key" + +char token_template[] = "\ +{\ + \"apiVersion\": \"client.authentication.k8s.io/v1beta1\",\ + \"kind\": \"ExecCredential\",\ + \"status\": {\ + \"token\": \"%s\"\ + }\ +}"; + +char certificate_template[] = "\ +{\ + \"apiVersion\": \"client.authentication.k8s.io/v1beta1\",\ + \"kind\": \"ExecCredential\",\ + \"status\": {\ + \"clientCertificateData\": \"%s\",\ + \"clientKeyData\": \"%s\"\ + }\ +}"; + +int main(int argc, char *argv[]) +{ + const char *client_certificate_data = secure_getenv(ENV_EXEC_CLIENT_CERTIFICATE_DATA); + const char *client_private_key = secure_getenv(ENV_EXEC_CLIENT_PRIVATE_KEY); + + if ((4 == argc) && argv[3]) { + // token is passed by command line argument + printf(token_template, argv[3]); + } else if ((client_certificate_data) && strlen(client_certificate_data) > 0 && (client_private_key) && strlen(client_private_key) > 0) { + // client certificate and private key are passed by environment variables + printf(certificate_template, client_certificate_data, client_private_key); + } else { + printf("Cannot get authentication data\n"); + } + + return 0; +} diff --git a/examples/list_pod_buffer/.gitignore b/examples/list_pod_buffer/.gitignore new file mode 100644 index 0000000..4841710 --- /dev/null +++ b/examples/list_pod_buffer/.gitignore @@ -0,0 +1 @@ +list_pod_buffer_bin diff --git a/examples/list_pod_buffer/CMakeLists.txt b/examples/list_pod_buffer/CMakeLists.txt new file mode 100644 index 0000000..46a76ba --- /dev/null +++ b/examples/list_pod_buffer/CMakeLists.txt @@ -0,0 +1,4 @@ +find_package(${pkgName} CONFIG REQUIRED COMPONENTS ${pkgName}) + +add_executable(list_pod_buffer main.c) +target_link_libraries(list_pod_buffer PRIVATE ${pkgName}::${pkgName}) \ No newline at end of file diff --git a/examples/list_pod_buffer/Makefile b/examples/list_pod_buffer/Makefile new file mode 100644 index 0000000..efaafc5 --- /dev/null +++ b/examples/list_pod_buffer/Makefile @@ -0,0 +1,17 @@ +INCLUDE:=-I../../kubernetes/ -I/usr/local/include/kubernetes/ +LIBS:=-L../../kubernetes/build -lyaml -lwebsockets -lkubernetes -L/usr/local/lib +CFLAGS:=-g +BIN:=list_pod_buffer_bin + +.PHONY : all clean test memcheck +all: + gcc main.c $(CFLAGS) $(INCLUDE) $(LIBS) -o $(BIN) + +test: + ./$(BIN) + +memcheck: + valgrind --tool=memcheck --leak-check=full ./$(BIN) + +clean: + rm ./$(BIN) diff --git a/examples/list_pod_buffer/main.c b/examples/list_pod_buffer/main.c new file mode 100644 index 0000000..b1475c0 --- /dev/null +++ b/examples/list_pod_buffer/main.c @@ -0,0 +1,141 @@ +#include +#include +#include + +#define ENV_KUBECONFIG "KUBECONFIG" +#ifndef _WIN32 +#define ENV_HOME "HOME" +#else +#define ENV_HOME "USERPROFILE" +#endif + +#define KUBE_CONFIG_DEFAULT_LOCATION "%s/.kube/config" + +static char *getWorkingConfigFile(const char *configFileNamePassedIn) +{ + char *configFileName = NULL; + const char *kubeconfig_env = NULL; + const char *homedir_env = NULL; + + if (configFileNamePassedIn) { + configFileName = strdup(configFileNamePassedIn); + } else { +#if defined(HAVE_SECURE_GETENV) + kubeconfig_env = secure_getenv(ENV_KUBECONFIG); +#elif defined(HAVE_GETENV) + kubeconfig_env = getenv(ENV_KUBECONFIG); +#endif + if (kubeconfig_env) { + configFileName = strdup(kubeconfig_env); + } else { +#if defined(HAVE_SECURE_GETENV) + homedir_env = secure_getenv(ENV_HOME); +#elif defined(HAVE_GETENV) + homedir_env = getenv(ENV_HOME); +#endif + if (homedir_env) { + int configFileNameSize = strlen(homedir_env) + strlen(KUBE_CONFIG_DEFAULT_LOCATION) + 1; + configFileName = calloc(configFileNameSize, sizeof(char)); + if (configFileName) { + snprintf(configFileName, configFileNameSize, KUBE_CONFIG_DEFAULT_LOCATION, homedir_env); + } + } + } + } + + return configFileName; +} + +static char *getFileData(const char *filePath) +{ + char *data = NULL; + char *kubeConfigFile = getWorkingConfigFile(filePath); + if (kubeConfigFile) { + FILE *kubeFile = fopen(kubeConfigFile, "r"); + if (kubeFile) { + fseek(kubeFile, 0, SEEK_END); + long fsize = ftell(kubeFile); + fseek(kubeFile, 0, SEEK_SET); + + data = calloc(1, fsize + 1); + if (data) { + fread(data, 1, fsize, kubeFile); + } + + fclose(kubeFile); + } + free(kubeConfigFile); + } + + return data; +} + +void list_pod(apiClient_t * apiClient) +{ + v1_pod_list_t *pod_list = NULL; + pod_list = CoreV1API_listNamespacedPod(apiClient, "default", /*namespace */ + NULL, /* pretty */ + NULL, /* allowWatchBookmarks */ + NULL, /* continue */ + NULL, /* fieldSelector */ + NULL, /* labelSelector */ + NULL, /* limit */ + NULL, /* resourceVersion */ + NULL, /* resourceVersionMatch */ + NULL, /* sendInitialEvents */ + NULL, /* timeoutSeconds */ + NULL /* watch */ + ); + printf("The return code of HTTP request=%ld\n", apiClient->response_code); + if (pod_list) { + printf("Get pod list:\n"); + listEntry_t *listEntry = NULL; + v1_pod_t *pod = NULL; + list_ForEach(listEntry, pod_list->items) { + pod = listEntry->data; + printf("\tThe pod name: %s\n", pod->metadata->name); + } + v1_pod_list_free(pod_list); + pod_list = NULL; + } else { + printf("Cannot get any pod.\n"); + } +} + +int main() +{ + char *basePath = NULL; + sslConfig_t *sslConfig = NULL; + list_t *apiKeys = NULL; + + char *dataBuffer = getFileData(NULL); /* NULL means loading configuration from $HOME/.kube/config */ + if (dataBuffer == NULL) { + printf("Cannot get kubernetes configuration from file.\n"); + return -1; + } + + int rc = load_kube_config_buffer(&basePath, &sslConfig, &apiKeys, dataBuffer); + if (rc != 0) { + printf("Cannot load kubernetes configuration.\n"); + return -1; + } + apiClient_t *apiClient = apiClient_create_with_base_path(basePath, sslConfig, apiKeys); + if (!apiClient) { + printf("Cannot create a kubernetes client.\n"); + return -1; + } + + list_pod(apiClient); + + apiClient_free(apiClient); + apiClient = NULL; + free_client_config(basePath, sslConfig, apiKeys); + basePath = NULL; + sslConfig = NULL; + apiKeys = NULL; + apiClient_unsetupGlobalEnv(); + free(dataBuffer); + dataBuffer = NULL; + + return 0; +}