Skip to content
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

add support to load kubernetes configuration for memory buffer #242

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions examples/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
71 changes: 71 additions & 0 deletions examples/exec_provider/list_pod_by_exec_provider.c~
ityuhui marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include <kube_config.h>
#include <apiClient.h>
#include <CoreV1API.h>
#include <malloc.h>
#include <stdio.h>
#include <errno.h>

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;
}
44 changes: 44 additions & 0 deletions examples/exec_provider/my_exec_provider.c~
ityuhui marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#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;
}
1 change: 1 addition & 0 deletions examples/list_pod_buffer/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
list_pod_buffer_bin
4 changes: 4 additions & 0 deletions examples/list_pod_buffer/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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})
17 changes: 17 additions & 0 deletions examples/list_pod_buffer/Makefile
Original file line number Diff line number Diff line change
@@ -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)
141 changes: 141 additions & 0 deletions examples/list_pod_buffer/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
#include <config/kube_config.h>
#include <api/CoreV1API.h>
#include <stdio.h>

#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;
}
49 changes: 37 additions & 12 deletions kubernetes/config/kube_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,24 +304,17 @@ static int kuberconfig_auth_provider(kubeconfig_property_t * current_user, kubec
return rc;
}

int load_kube_config(char **pBasePath, sslConfig_t ** pSslConfig, list_t ** pApiKeys, const char *configFileName)
int load_kube_config_common(char **pBasePath, sslConfig_t ** pSslConfig, list_t ** pApiKeys, kubeconfig_t * kubeconfig)
{
static char fname[] = "load_kube_config()";
static char fname[] = "load_kube_config_common()";
int rc = 0;
const kubeconfig_property_t *current_context = NULL;
const kubeconfig_property_t *current_cluster = NULL;
kubeconfig_property_t *current_user = NULL;

kubeconfig_t *kubeconfig = kubeconfig_create();
if (!kubeconfig) {
fprintf(stderr, "%s: Cannot create kubeconfig.[%s]\n", fname, strerror(errno));
return -1;
}

kubeconfig->fileName = getWorkingConfigFile(configFileName);
rc = kubeyaml_load_kubeconfig(kubeconfig);
if (0 != rc) {
fprintf(stderr, "%s: Cannot load the kubeconfig %s\n", fname, kubeconfig->fileName);
fprintf(stderr, "%s: Cannot load the kubeconfig %s\n", fname, kubeconfig->fileName ? kubeconfig->fileName : kubeconfig->buffer);
rc = -1;
goto end;
}
Expand Down Expand Up @@ -393,8 +386,40 @@ int load_kube_config(char **pBasePath, sslConfig_t ** pSslConfig, list_t ** pApi
}

end:
kubeconfig_free(kubeconfig);
kubeconfig = NULL;
return rc;
}

int load_kube_config(char **pBasePath, sslConfig_t ** pSslConfig, list_t ** pApiKeys, const char *configFileName)
{
static char fname[] = "load_kube_config()";
int rc = 0;

kubeconfig_t kubeconfig;
memset(&kubeconfig, 0, sizeof(kubeconfig_t));

kubeconfig.fileName = getWorkingConfigFile(configFileName);

rc = load_kube_config_common(pBasePath, pSslConfig, pApiKeys, &kubeconfig);

kubeconfig_free_members(&kubeconfig);

return rc;
}

int load_kube_config_buffer(char **pBasePath, sslConfig_t ** pSslConfig, list_t ** pApiKeys, const char *buffer)
{
static char fname[] = "load_kube_config_buffer()";
int rc = 0;

kubeconfig_t kubeconfig;
memset(&kubeconfig, 0, sizeof(kubeconfig_t));

kubeconfig.buffer = strdup(buffer);

rc = load_kube_config_common(pBasePath, pSslConfig, pApiKeys, &kubeconfig);

kubeconfig_free_members(&kubeconfig);

return rc;
}

Expand Down
Loading
Loading