Merge pull request #9 from ityuhui/yhkubeconfig
[Configuration]Support X509 client certificate in kube config file
This commit is contained in:
5
code-check/code-static-check.sh
Normal file
5
code-check/code-static-check.sh
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Usage:
|
||||||
|
# sh ./code-static-check.sh ${source_dir}
|
||||||
|
|
||||||
|
cppcheck --enable=all $*
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
INCLUDE:=-I../../kubernetes/include -I../../kubernetes/model -I../../kubernetes/api
|
INCLUDE:=-I../../kubernetes/include -I../../kubernetes/model -I../../kubernetes/api -I../../kubernetes/config
|
||||||
LIBS:=-L../../kubernetes/build -lkubernetes -lcurl -lpthread -lssl -lz
|
LIBS:=-L../../kubernetes/build -lkubernetes -lcurl -lyaml -lpthread -lssl -lz
|
||||||
CFLAGS:=-g
|
CFLAGS:=-g
|
||||||
|
|
||||||
all:
|
all:
|
||||||
|
|||||||
@@ -1,22 +1,10 @@
|
|||||||
|
#include <kube_config.h>
|
||||||
#include <apiClient.h>
|
#include <apiClient.h>
|
||||||
#include <CoreV1API.h>
|
#include <CoreV1API.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
// kubectl proxy server
|
|
||||||
#define K8S_APISERVER_BASEPATH "http://localhost:8001"
|
|
||||||
|
|
||||||
// Alternately from within a Kubernetes cluster:
|
|
||||||
// #define K8S_APISERVER_BASEPATH https://your.server.here
|
|
||||||
|
|
||||||
#define K8S_TOKEN_FILE_IN_CLUSTER "/var/run/secrets/kubernetes.io/serviceaccount/token"
|
|
||||||
#define K8S_TOKEN_BUF_SIZE 1024
|
|
||||||
#define K8S_AUTH_KEY "Authorization"
|
|
||||||
#define K8S_AUTH_VALUE_TEMPLATE "Bearer %s"
|
|
||||||
|
|
||||||
apiClient_t *g_k8sAPIConnector;
|
|
||||||
|
|
||||||
void create_a_pod(apiClient_t * apiClient)
|
void create_a_pod(apiClient_t * apiClient)
|
||||||
{
|
{
|
||||||
char *namespace = "default";
|
char *namespace = "default";
|
||||||
@@ -54,57 +42,34 @@ void create_a_pod(apiClient_t * apiClient)
|
|||||||
v1_pod_free(apod);
|
v1_pod_free(apod);
|
||||||
}
|
}
|
||||||
|
|
||||||
int loadK8sConfigInCluster(char *token, int token_buf_size)
|
|
||||||
{
|
|
||||||
static char fname[] = "loadK8sConfigInCluster()";
|
|
||||||
|
|
||||||
FILE *fp;
|
|
||||||
fp = fopen(K8S_TOKEN_FILE_IN_CLUSTER, "r");
|
|
||||||
|
|
||||||
if (fp == NULL) {
|
|
||||||
if (errno == ENOENT) {
|
|
||||||
printf("%s: The file %s does not exist.", fname, K8S_TOKEN_FILE_IN_CLUSTER);
|
|
||||||
return (-1);
|
|
||||||
} else {
|
|
||||||
printf("%s: Failed to open file %s.", fname, K8S_TOKEN_FILE_IN_CLUSTER);
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (fgets(token, token_buf_size, fp) != NULL) {
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%s\n", token);
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int init_k8s_connector(const char *token_out_of_cluster)
|
|
||||||
{
|
|
||||||
list_t *apiKeys;
|
|
||||||
apiKeys = list_create();
|
|
||||||
|
|
||||||
char *keyToken = strdup(K8S_AUTH_KEY);
|
|
||||||
|
|
||||||
char valueToken[K8S_TOKEN_BUF_SIZE];
|
|
||||||
memset(valueToken, 0, sizeof(valueToken));
|
|
||||||
|
|
||||||
sprintf(valueToken, K8S_AUTH_VALUE_TEMPLATE, token_out_of_cluster);
|
|
||||||
|
|
||||||
keyValuePair_t *keyPairToken = keyValuePair_create(keyToken, valueToken);
|
|
||||||
list_addElement(apiKeys, keyPairToken);
|
|
||||||
|
|
||||||
g_k8sAPIConnector = apiClient_create_with_base_path(K8S_APISERVER_BASEPATH, NULL, apiKeys);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
init_k8s_connector(argv[1]);
|
|
||||||
|
|
||||||
create_a_pod(g_k8sAPIConnector);
|
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, NULL);
|
||||||
|
if (0 == rc) {
|
||||||
|
k8sApiClient = apiClient_create_with_base_path(baseName, sslConfig, apiKeys);
|
||||||
|
} else {
|
||||||
|
printf("Cannot load kubernetes configuration.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (k8sApiClient) {
|
||||||
|
create_a_pod(k8sApiClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
free_client_config(baseName, sslConfig, apiKeys);
|
||||||
|
baseName = NULL;
|
||||||
|
sslConfig = NULL;
|
||||||
|
apiKeys = NULL;
|
||||||
|
|
||||||
|
apiClient_free(k8sApiClient);
|
||||||
|
k8sApiClient = NULL;
|
||||||
|
|
||||||
apiClient_free(g_k8sAPIConnector);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
INCLUDE:=-I../../kubernetes/include -I../../kubernetes/model -I../../kubernetes/api
|
INCLUDE:=-I../../kubernetes/include -I../../kubernetes/model -I../../kubernetes/api -I../../kubernetes/config
|
||||||
LIBS:=-L../../kubernetes/build -lkubernetes -lcurl -lpthread -lssl -lz
|
LIBS:=-L../../kubernetes/build -lkubernetes -lcurl -lyaml -lpthread -lssl -lz
|
||||||
CFLAGS:=-g
|
CFLAGS:=-g
|
||||||
|
|
||||||
all:
|
all:
|
||||||
|
|||||||
@@ -1,22 +1,10 @@
|
|||||||
|
#include <kube_config.h>
|
||||||
#include <apiClient.h>
|
#include <apiClient.h>
|
||||||
#include <CoreV1API.h>
|
#include <CoreV1API.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
// kubectl proxy server
|
|
||||||
#define K8S_APISERVER_BASEPATH "http://localhost:8001"
|
|
||||||
|
|
||||||
// Alternately from within a Kubernetes cluster:
|
|
||||||
// #define K8S_APISERVER_BASEPATH https://your.server.here
|
|
||||||
|
|
||||||
#define K8S_TOKEN_FILE_IN_CLUSTER "/var/run/secrets/kubernetes.io/serviceaccount/token"
|
|
||||||
#define K8S_TOKEN_BUF_SIZE 1024
|
|
||||||
#define K8S_AUTH_KEY "Authorization"
|
|
||||||
#define K8S_AUTH_VALUE_TEMPLATE "Bearer %s"
|
|
||||||
|
|
||||||
apiClient_t *g_k8sAPIConnector;
|
|
||||||
|
|
||||||
void list_pod(apiClient_t * apiClient)
|
void list_pod(apiClient_t * apiClient)
|
||||||
{
|
{
|
||||||
v1_pod_list_t *pod_list = NULL;
|
v1_pod_list_t *pod_list = NULL;
|
||||||
@@ -31,71 +19,48 @@ void list_pod(apiClient_t * apiClient)
|
|||||||
0, /* timeoutSeconds */
|
0, /* timeoutSeconds */
|
||||||
0 /* watch */
|
0 /* watch */
|
||||||
);
|
);
|
||||||
printf("return code=%ld\n", apiClient->response_code);
|
printf("The return code of HTTP request=%ld\n", apiClient->response_code);
|
||||||
if (pod_list) {
|
if (pod_list) {
|
||||||
printf("Get pod list.\n");
|
printf("Get pod list:\n");
|
||||||
listEntry_t *listEntry = NULL;
|
listEntry_t *listEntry = NULL;
|
||||||
v1_pod_t *pod = NULL;
|
v1_pod_t *pod = NULL;
|
||||||
list_ForEach(listEntry, pod_list->items) {
|
list_ForEach(listEntry, pod_list->items) {
|
||||||
pod = listEntry->data;
|
pod = listEntry->data;
|
||||||
printf("pod name=%s\n", pod->metadata->name);
|
printf("\tThe pod name: %s\n", pod->metadata->name);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("Cannot list any pod.\n");
|
printf("Cannot get any pod.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int loadK8sConfigInCluster(char *token, int token_buf_size)
|
|
||||||
{
|
|
||||||
static char fname[] = "loadK8sConfigInCluster()";
|
|
||||||
|
|
||||||
FILE *fp;
|
|
||||||
fp = fopen(K8S_TOKEN_FILE_IN_CLUSTER, "r");
|
|
||||||
|
|
||||||
if (fp == NULL) {
|
|
||||||
if (errno == ENOENT) {
|
|
||||||
printf("%s: The file %s does not exist.", fname, K8S_TOKEN_FILE_IN_CLUSTER);
|
|
||||||
return (-1);
|
|
||||||
} else {
|
|
||||||
printf("%s: Failed to open file %s.", fname, K8S_TOKEN_FILE_IN_CLUSTER);
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (fgets(token, token_buf_size, fp) != NULL) {
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%s\n", token);
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int init_k8s_connector(const char *token_out_of_cluster)
|
|
||||||
{
|
|
||||||
list_t *apiKeys;
|
|
||||||
apiKeys = list_create();
|
|
||||||
|
|
||||||
char *keyToken = strdup(K8S_AUTH_KEY);
|
|
||||||
|
|
||||||
char valueToken[K8S_TOKEN_BUF_SIZE];
|
|
||||||
memset(valueToken, 0, sizeof(valueToken));
|
|
||||||
|
|
||||||
sprintf(valueToken, K8S_AUTH_VALUE_TEMPLATE, token_out_of_cluster);
|
|
||||||
|
|
||||||
keyValuePair_t *keyPairToken = keyValuePair_create(keyToken, valueToken);
|
|
||||||
list_addElement(apiKeys, keyPairToken);
|
|
||||||
|
|
||||||
g_k8sAPIConnector = apiClient_create_with_base_path(K8S_APISERVER_BASEPATH, NULL, apiKeys);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
init_k8s_connector(argv[1]);
|
int rc = 0;
|
||||||
|
|
||||||
list_pod(g_k8sAPIConnector);
|
char *baseName = NULL;
|
||||||
|
sslConfig_t *sslConfig = NULL;
|
||||||
|
list_t *apiKeys = NULL;
|
||||||
|
apiClient_t *k8sApiClient = NULL;
|
||||||
|
|
||||||
apiClient_free(g_k8sAPIConnector);
|
rc = load_kube_config(&baseName, &sslConfig, &apiKeys, NULL);
|
||||||
|
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;
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ set(CMAKE_VISIBILITY_INLINES_HIDDEN OFF)
|
|||||||
set(CMAKE_BUILD_TYPE Debug)
|
set(CMAKE_BUILD_TYPE Debug)
|
||||||
|
|
||||||
set(pkgName "kubernetes")
|
set(pkgName "kubernetes")
|
||||||
|
ADD_DEFINITIONS(-DOPENSSL)
|
||||||
|
|
||||||
find_package(CURL 7.58.0 REQUIRED)
|
find_package(CURL 7.58.0 REQUIRED)
|
||||||
if(CURL_FOUND)
|
if(CURL_FOUND)
|
||||||
@@ -18,7 +19,11 @@ else(CURL_FOUND)
|
|||||||
message(FATAL_ERROR "Could not find the CURL library and development files.")
|
message(FATAL_ERROR "Could not find the CURL library and development files.")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
set(SRCS
|
set(SRCS
|
||||||
|
config/kube_config_model.c
|
||||||
|
config/kube_config_yaml.c
|
||||||
|
config/kube_config.c
|
||||||
src/list.c
|
src/list.c
|
||||||
src/apiKey.c
|
src/apiKey.c
|
||||||
src/apiClient.c
|
src/apiClient.c
|
||||||
@@ -770,6 +775,9 @@ set(SRCS
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(HDRS
|
set(HDRS
|
||||||
|
config/kube_config_model.h
|
||||||
|
config/kube_config_yaml.h
|
||||||
|
config/kube_config.h
|
||||||
include/apiClient.h
|
include/apiClient.h
|
||||||
include/list.h
|
include/list.h
|
||||||
include/keyValuePair.h
|
include/keyValuePair.h
|
||||||
|
|||||||
264
kubernetes/config/kube_config.c
Normal file
264
kubernetes/config/kube_config.c
Normal file
@@ -0,0 +1,264 @@
|
|||||||
|
#include "kube_config.h"
|
||||||
|
#include "kube_config_yaml.h"
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define ENV_KUBECONFIG "KUBECONFIG"
|
||||||
|
#define ENV_HOME "HOME"
|
||||||
|
#define KUBE_CONFIG_DEFAULT_LOCATION "%s/.kube/config"
|
||||||
|
#define KUBE_CONFIG_TEMPFILE_NAME_TEMPLATE "/tmp/kubeconfig-XXXXXX"
|
||||||
|
|
||||||
|
static int setBasePath(char **pBasePath, char *basePath)
|
||||||
|
{
|
||||||
|
char *_basePath = strdup(basePath);
|
||||||
|
if (_basePath) {
|
||||||
|
*pBasePath = _basePath;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *kubeconfig_mk_cert_key_tempfile(const char *b64data)
|
||||||
|
{
|
||||||
|
static char fname[] = "kubeconfig_mk_tempfile()";
|
||||||
|
|
||||||
|
int decoded_bytes = 0;
|
||||||
|
char *b64decode = base64decode(b64data, strlen(b64data), &decoded_bytes);
|
||||||
|
if (!b64decode || 0 == decoded_bytes) {
|
||||||
|
fprintf(stderr, "%s: Base64 decodes failed.\n", fname);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char tempfile_name_template[] = KUBE_CONFIG_TEMPFILE_NAME_TEMPLATE;
|
||||||
|
int fd = mkstemp(tempfile_name_template);
|
||||||
|
if (-1 == fd) {
|
||||||
|
fprintf(stderr, "%s: Creating temp file for kubeconfig failed with error [%s]\n", fname, strerror(errno));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rc = write(fd, b64decode, decoded_bytes);
|
||||||
|
close(fd);
|
||||||
|
if (-1 == rc) {
|
||||||
|
fprintf(stderr, "%s: Writing temp file failed with error [%s]\n", fname, strerror(errno));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return strdup(tempfile_name_template);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void kubeconfig_rm_tempfile(const char *filename)
|
||||||
|
{
|
||||||
|
if (filename) {
|
||||||
|
unlink(filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void unsetSslConfig(sslConfig_t * sslConfig)
|
||||||
|
{
|
||||||
|
if (!sslConfig) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sslConfig->clientCertFile) {
|
||||||
|
kubeconfig_rm_tempfile(sslConfig->clientCertFile);
|
||||||
|
}
|
||||||
|
if (sslConfig->clientKeyFile) {
|
||||||
|
kubeconfig_rm_tempfile(sslConfig->clientKeyFile);
|
||||||
|
}
|
||||||
|
if (sslConfig->CACertFile) {
|
||||||
|
kubeconfig_rm_tempfile(sslConfig->CACertFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int setSslConfig(sslConfig_t ** pSslConfig, const kubeconfig_property_t * cluster, const kubeconfig_property_t * user)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
char *client_cert_file = NULL;
|
||||||
|
char *client_key_file = NULL;
|
||||||
|
char *ca_file = NULL;
|
||||||
|
int insecure_skip_tls_verify = 0;
|
||||||
|
|
||||||
|
if (user) {
|
||||||
|
if (user->client_certificate_data) {
|
||||||
|
client_cert_file = kubeconfig_mk_cert_key_tempfile(user->client_certificate_data);
|
||||||
|
}
|
||||||
|
if (user->client_key_data) {
|
||||||
|
client_key_file = kubeconfig_mk_cert_key_tempfile(user->client_key_data);
|
||||||
|
}
|
||||||
|
insecure_skip_tls_verify = user->insecure_skip_tls_verify;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cluster) {
|
||||||
|
if ((0 == insecure_skip_tls_verify) && (cluster->certificate_authority_data)) {
|
||||||
|
ca_file = kubeconfig_mk_cert_key_tempfile(cluster->certificate_authority_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sslConfig_t *sc = sslConfig_create(client_cert_file, client_key_file, ca_file, insecure_skip_tls_verify);
|
||||||
|
if (sc) {
|
||||||
|
*pSslConfig = sc;
|
||||||
|
} else {
|
||||||
|
rc = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client_cert_file) {
|
||||||
|
free(client_cert_file);
|
||||||
|
}
|
||||||
|
if (client_key_file) {
|
||||||
|
free(client_key_file);
|
||||||
|
}
|
||||||
|
if (ca_file) {
|
||||||
|
free(ca_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int setApiKeys(list_t ** pApiKeys, const kubeconfig_property_t * user)
|
||||||
|
{
|
||||||
|
list_t *apiKeys = list_create();
|
||||||
|
if (apiKeys) {
|
||||||
|
|
||||||
|
/* under development for the token based authentication */
|
||||||
|
|
||||||
|
*pApiKeys = apiKeys;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
kubeconfig_env = getenv(ENV_KUBECONFIG);
|
||||||
|
if (kubeconfig_env) {
|
||||||
|
configFileName = strdup(kubeconfig_env);
|
||||||
|
} else {
|
||||||
|
homedir_env = getenv(ENV_HOME);
|
||||||
|
if (homedir_env) {
|
||||||
|
configFileName = calloc(strlen(homedir_env) + strlen(KUBE_CONFIG_DEFAULT_LOCATION) + 1, sizeof(char));
|
||||||
|
if (configFileName) {
|
||||||
|
sprintf(configFileName, KUBE_CONFIG_DEFAULT_LOCATION, homedir_env);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return configFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const kubeconfig_property_t *kubeconfig_get_current_property(kubeconfig_property_t ** properties, int properties_count, const char *property_name)
|
||||||
|
{
|
||||||
|
const kubeconfig_property_t *current_property = NULL;
|
||||||
|
|
||||||
|
if (NULL == properties || NULL == property_name) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < properties_count; i++) {
|
||||||
|
if (0 == strcmp(properties[i]->name, property_name)) {
|
||||||
|
current_property = properties[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return current_property;
|
||||||
|
}
|
||||||
|
|
||||||
|
int load_kube_config(char **pBasePath, sslConfig_t ** pSslConfig, list_t ** pApiKeys, const char *configFileName)
|
||||||
|
{
|
||||||
|
static char fname[] = "load_kube_config()";
|
||||||
|
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
const kubeconfig_property_t *current_context = NULL;
|
||||||
|
const kubeconfig_property_t *current_cluster = NULL;
|
||||||
|
const 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);
|
||||||
|
rc = -1;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_context = kubeconfig_get_current_property(kubeconfig->contexts, kubeconfig->contexts_count, kubeconfig->current_context);
|
||||||
|
if (!current_context) {
|
||||||
|
fprintf(stderr, "%s: Cannot get the current context by the kubeconfig.\n", fname);
|
||||||
|
rc = -1;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_cluster = kubeconfig_get_current_property(kubeconfig->clusters, kubeconfig->clusters_count, current_context->cluster);
|
||||||
|
if (!current_cluster) {
|
||||||
|
fprintf(stderr, "%s: Cannot get the current cluster information by the kubeconfig.\n", fname);
|
||||||
|
rc = -1;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_user = kubeconfig_get_current_property(kubeconfig->users, kubeconfig->users_count, current_context->user);
|
||||||
|
if (!current_user) {
|
||||||
|
fprintf(stderr, "%s: Cannot get the current user information by the kubeconfig.\n", fname);
|
||||||
|
rc = -1;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_cluster && current_cluster->server) {
|
||||||
|
rc = setBasePath(pBasePath, current_cluster->server);
|
||||||
|
if (0 != rc) {
|
||||||
|
fprintf(stderr, "%s: Cannot set the base path for API server.\n", fname);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_cluster || current_user) {
|
||||||
|
rc = setSslConfig(pSslConfig, current_cluster, current_user);
|
||||||
|
if (0 != rc) {
|
||||||
|
fprintf(stderr, "%s: Cannot set the SSL Configuration for the client.\n", fname);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_user) {
|
||||||
|
rc = setApiKeys(pApiKeys, current_user);
|
||||||
|
if (0 != rc) {
|
||||||
|
fprintf(stderr, "%s: Cannot set the tokens for the client.\n", fname);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
kubeconfig_free(kubeconfig);
|
||||||
|
kubeconfig = NULL;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_client_config(char *basePath, sslConfig_t * sslConfig, list_t * apiKeys)
|
||||||
|
{
|
||||||
|
if (basePath) {
|
||||||
|
free(basePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sslConfig) {
|
||||||
|
unsetSslConfig(sslConfig);
|
||||||
|
sslConfig_free(sslConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (apiKeys) {
|
||||||
|
list_free(apiKeys);
|
||||||
|
}
|
||||||
|
}
|
||||||
82
kubernetes/config/kube_config.h
Normal file
82
kubernetes/config/kube_config.h
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
#ifndef _KUBE_CONFIG_H
|
||||||
|
#define _KUBE_CONFIG_H
|
||||||
|
|
||||||
|
#include "../include/apiClient.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* load_kube_config
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Load kubernetes cluster configuration from the file specified
|
||||||
|
* by parameter or default location: $HOME/.kube/config
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Return:
|
||||||
|
*
|
||||||
|
* 0 Success
|
||||||
|
* -1 Failed
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Parameter:
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* IN:
|
||||||
|
|
||||||
|
* configFileName : kubernetes cluster configuration file name
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* OUT:
|
||||||
|
*
|
||||||
|
* pBasePath: The pointer to API server address
|
||||||
|
* pSslConfig: The pointer to SSL configuration for client
|
||||||
|
* pApiKeys: The pointer to API tokens for client
|
||||||
|
*
|
||||||
|
* The memory will be allocated inside this function. User
|
||||||
|
* should call free_client_config to free the memory after
|
||||||
|
* these parameters are not used.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
int load_kube_config(char **pBasePath, sslConfig_t ** pSslConfig, list_t ** pApiKeys, const char *configFileName);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* free_client_config
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
*
|
||||||
|
* Help function to free the memory for the client configuration
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Return:
|
||||||
|
*
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Parameter:
|
||||||
|
*
|
||||||
|
* IN:
|
||||||
|
*
|
||||||
|
* basePath: API server address
|
||||||
|
* sslConfig: SSL configuration for client
|
||||||
|
* apiKeys: API tokens for client
|
||||||
|
*
|
||||||
|
* OUT:
|
||||||
|
*
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void free_client_config(char *basePath, sslConfig_t * sslConfig, list_t * apiKeys);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* _KUBE_CONFIG_H */
|
||||||
209
kubernetes/config/kube_config_model.c
Normal file
209
kubernetes/config/kube_config_model.c
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
#include "kube_config_model.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
kubeconfig_auth_provider_t *kubeconfig_auth_provider_create()
|
||||||
|
{
|
||||||
|
kubeconfig_auth_provider_t *provider = calloc(1, sizeof(kubeconfig_auth_provider_t));
|
||||||
|
return provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
void kubeconfig_auth_provider_free(kubeconfig_auth_provider_t * provider)
|
||||||
|
{
|
||||||
|
if (!provider) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (provider->name) {
|
||||||
|
free(provider->name);
|
||||||
|
provider->name = NULL;
|
||||||
|
}
|
||||||
|
if (provider->id_token) {
|
||||||
|
free(provider->id_token);
|
||||||
|
provider->id_token = NULL;
|
||||||
|
}
|
||||||
|
if (provider->cmd_path) {
|
||||||
|
free(provider->cmd_path);
|
||||||
|
provider->cmd_path = NULL;
|
||||||
|
}
|
||||||
|
if (provider->access_token) {
|
||||||
|
free(provider->access_token);
|
||||||
|
provider->access_token = NULL;
|
||||||
|
}
|
||||||
|
if (provider->expires_on) {
|
||||||
|
free(provider->expires_on);
|
||||||
|
provider->expires_on = NULL;
|
||||||
|
}
|
||||||
|
if (provider->expiry) {
|
||||||
|
free(provider->expiry);
|
||||||
|
provider->expiry = NULL;
|
||||||
|
}
|
||||||
|
if (provider->idp_certificate_authority_data) {
|
||||||
|
free(provider->idp_certificate_authority_data);
|
||||||
|
provider->idp_certificate_authority_data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
kubeconfig_exec_t *kubeconfig_exec_create()
|
||||||
|
{
|
||||||
|
kubeconfig_exec_t *exec = calloc(1, sizeof(kubeconfig_exec_t));
|
||||||
|
return exec;
|
||||||
|
}
|
||||||
|
|
||||||
|
void kubeconfig_exec_free(kubeconfig_exec_t * exec)
|
||||||
|
{
|
||||||
|
if (!exec) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exec->command) {
|
||||||
|
free(exec->command);
|
||||||
|
exec->command = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(exec);
|
||||||
|
}
|
||||||
|
|
||||||
|
kubeconfig_property_t *kubeconfig_property_create(kubeconfig_property_type_t type)
|
||||||
|
{
|
||||||
|
kubeconfig_property_t *property = calloc(1, sizeof(kubeconfig_property_t));
|
||||||
|
property->type = type;
|
||||||
|
return property;
|
||||||
|
}
|
||||||
|
|
||||||
|
void kubeconfig_property_free(kubeconfig_property_t * property)
|
||||||
|
{
|
||||||
|
if (!property) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (property->name) {
|
||||||
|
free(property->name);
|
||||||
|
property->name = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (KUBECONFIG_PROPERTY_TYPE_CLUSTER == property->type) {
|
||||||
|
if (property->server) {
|
||||||
|
free(property->server);
|
||||||
|
property->server = NULL;
|
||||||
|
}
|
||||||
|
if (property->certificate_authority_data) {
|
||||||
|
free(property->certificate_authority_data);
|
||||||
|
property->certificate_authority_data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (KUBECONFIG_PROPERTY_TYPE_USER == property->type) {
|
||||||
|
if (property->client_certificate_data) {
|
||||||
|
free(property->client_certificate_data);
|
||||||
|
property->client_certificate_data = NULL;
|
||||||
|
}
|
||||||
|
if (property->client_key_data) {
|
||||||
|
free(property->client_key_data);
|
||||||
|
property->client_key_data = NULL;
|
||||||
|
}
|
||||||
|
if (property->username) {
|
||||||
|
free(property->username);
|
||||||
|
property->username = NULL;
|
||||||
|
}
|
||||||
|
if (property->password) {
|
||||||
|
free(property->password);
|
||||||
|
property->password = NULL;
|
||||||
|
}
|
||||||
|
if (property->auth_provider) {
|
||||||
|
kubeconfig_auth_provider_free(property->auth_provider);
|
||||||
|
property->auth_provider = NULL;
|
||||||
|
}
|
||||||
|
if (property->exec) {
|
||||||
|
kubeconfig_exec_free(property->exec);
|
||||||
|
property->exec = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (KUBECONFIG_PROPERTY_TYPE_CONTEXT == property->type) {
|
||||||
|
if (property->cluster) {
|
||||||
|
free(property->cluster);
|
||||||
|
property->cluster = NULL;
|
||||||
|
}
|
||||||
|
if (property->user) {
|
||||||
|
free(property->user);
|
||||||
|
property->user = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(property);
|
||||||
|
}
|
||||||
|
|
||||||
|
kubeconfig_property_t **kubeconfig_properties_create(int contexts_count, kubeconfig_property_type_t type)
|
||||||
|
{
|
||||||
|
kubeconfig_property_t **properties = (kubeconfig_property_t **) calloc(contexts_count, sizeof(kubeconfig_property_t *));
|
||||||
|
int i = 0;
|
||||||
|
for (i = 0; i < contexts_count; i++) {
|
||||||
|
properties[i] = kubeconfig_property_create(type);
|
||||||
|
}
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
void kubeconfig_properties_free(kubeconfig_property_t ** properties, int properties_count)
|
||||||
|
{
|
||||||
|
if (!properties) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < properties_count; i++) {
|
||||||
|
if (properties[i]) {
|
||||||
|
kubeconfig_property_free(properties[i]);
|
||||||
|
properties[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
kubeconfig_t *kubeconfig_create()
|
||||||
|
{
|
||||||
|
kubeconfig_t *config = calloc(1, sizeof(kubeconfig_t));
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
void kubeconfig_free(kubeconfig_t * kubeconfig)
|
||||||
|
{
|
||||||
|
if (!kubeconfig) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kubeconfig->fileName) {
|
||||||
|
free(kubeconfig->fileName);
|
||||||
|
kubeconfig->fileName = NULL;
|
||||||
|
}
|
||||||
|
if (kubeconfig->apiVersion) {
|
||||||
|
free(kubeconfig->apiVersion);
|
||||||
|
kubeconfig->apiVersion = NULL;
|
||||||
|
}
|
||||||
|
if (kubeconfig->kind) {
|
||||||
|
free(kubeconfig->kind);
|
||||||
|
kubeconfig->kind = NULL;
|
||||||
|
}
|
||||||
|
if (kubeconfig->preferences) {
|
||||||
|
free(kubeconfig->preferences);
|
||||||
|
kubeconfig->preferences = NULL;
|
||||||
|
}
|
||||||
|
if (kubeconfig->current_context) {
|
||||||
|
free(kubeconfig->current_context);
|
||||||
|
kubeconfig->current_context = NULL;
|
||||||
|
}
|
||||||
|
if (kubeconfig->clusters) {
|
||||||
|
kubeconfig_properties_free(kubeconfig->clusters, kubeconfig->clusters_count);
|
||||||
|
kubeconfig->clusters = NULL;
|
||||||
|
}
|
||||||
|
if (kubeconfig->users) {
|
||||||
|
kubeconfig_properties_free(kubeconfig->users, kubeconfig->users_count);
|
||||||
|
kubeconfig->users = NULL;
|
||||||
|
}
|
||||||
|
if (kubeconfig->contexts) {
|
||||||
|
kubeconfig_properties_free(kubeconfig->contexts, kubeconfig->contexts_count);
|
||||||
|
kubeconfig->contexts = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(kubeconfig);
|
||||||
|
}
|
||||||
84
kubernetes/config/kube_config_model.h
Normal file
84
kubernetes/config/kube_config_model.h
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
#ifndef _KUBE_CONFIG_MODEL_H
|
||||||
|
#define _KUBE_CONFIG_MODEL_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct kubeconfig_auth_provider_t {
|
||||||
|
char *name;
|
||||||
|
char *id_token;
|
||||||
|
char *cmd_path;
|
||||||
|
char *access_token;
|
||||||
|
char *expires_on;
|
||||||
|
char *expiry;
|
||||||
|
char *idp_certificate_authority_data;
|
||||||
|
} kubeconfig_auth_provider_t;
|
||||||
|
|
||||||
|
typedef struct kubeconfig_exec_t {
|
||||||
|
char *command;
|
||||||
|
} kubeconfig_exec_t;
|
||||||
|
|
||||||
|
typedef enum kubeconfig_property_type_t {
|
||||||
|
KUBECONFIG_PROPERTY_TYPE_CONTEXT = 1,
|
||||||
|
KUBECONFIG_PROPERTY_TYPE_CLUSTER,
|
||||||
|
KUBECONFIG_PROPERTY_TYPE_USER
|
||||||
|
} kubeconfig_property_type_t;
|
||||||
|
|
||||||
|
typedef struct kubeconfig_property_t {
|
||||||
|
kubeconfig_property_type_t type;
|
||||||
|
char *name;
|
||||||
|
union {
|
||||||
|
struct { /* context */
|
||||||
|
char *cluster;
|
||||||
|
char *user;
|
||||||
|
};
|
||||||
|
struct { /* cluster */
|
||||||
|
char *server;
|
||||||
|
char *certificate_authority_data;
|
||||||
|
};
|
||||||
|
struct { /* user */
|
||||||
|
char *client_certificate_data;
|
||||||
|
char *client_key_data;
|
||||||
|
kubeconfig_auth_provider_t *auth_provider;
|
||||||
|
kubeconfig_exec_t *exec;
|
||||||
|
int insecure_skip_tls_verify;
|
||||||
|
char *username;
|
||||||
|
char *password;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} kubeconfig_property_t;
|
||||||
|
|
||||||
|
typedef struct kubeconfig_t {
|
||||||
|
char *fileName;
|
||||||
|
char *apiVersion;
|
||||||
|
char *preferences;
|
||||||
|
char *kind;
|
||||||
|
char *current_context;
|
||||||
|
kubeconfig_property_t **contexts;
|
||||||
|
int contexts_count;
|
||||||
|
kubeconfig_property_t **clusters;
|
||||||
|
int clusters_count;
|
||||||
|
kubeconfig_property_t **users;
|
||||||
|
int users_count;
|
||||||
|
} kubeconfig_t;
|
||||||
|
|
||||||
|
kubeconfig_auth_provider_t *kubeconfig_auth_provider_create();
|
||||||
|
void kubeconfig_auth_provider_free(kubeconfig_auth_provider_t * provider);
|
||||||
|
|
||||||
|
kubeconfig_exec_t *kubeconfig_exec_create();
|
||||||
|
void kubeconfig_exec_free(kubeconfig_exec_t * exec);
|
||||||
|
|
||||||
|
kubeconfig_property_t *kubeconfig_property_create(kubeconfig_property_type_t type);
|
||||||
|
void kubeconfig_property_free(kubeconfig_property_t * property);
|
||||||
|
|
||||||
|
kubeconfig_property_t **kubeconfig_properties_create(int contexts_count, kubeconfig_property_type_t type);
|
||||||
|
void kubeconfig_properties_free(kubeconfig_property_t ** properties, int properties_count);
|
||||||
|
|
||||||
|
kubeconfig_t *kubeconfig_create();
|
||||||
|
void kubeconfig_free(kubeconfig_t * kubeconfig);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* _KUBE_CONFIG_MODEL_H */
|
||||||
263
kubernetes/config/kube_config_yaml.c
Normal file
263
kubernetes/config/kube_config_yaml.c
Normal file
@@ -0,0 +1,263 @@
|
|||||||
|
#include <yaml.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include "kube_config_yaml.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
A valid sequence of events should obey the grammar :
|
||||||
|
|
||||||
|
stream :: = STREAM - START document * STREAM - END
|
||||||
|
document :: = DOCUMENT - START node DOCUMENT - END
|
||||||
|
node :: = ALIAS | SCALAR | sequence | mapping
|
||||||
|
sequence :: = SEQUENCE - START node * SEQUENCE - END
|
||||||
|
mapping :: = MAPPING - START(node node) * MAPPING - END
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define KEY_APIVERSION "apiVersion"
|
||||||
|
#define KEY_KIND "kind"
|
||||||
|
#define KEY_CURRENT_CONTEXT "current-context"
|
||||||
|
#define KEY_CLUSTERS "clusters"
|
||||||
|
#define KEY_CLUSTER "cluster"
|
||||||
|
#define KEY_CONTEXTS "contexts"
|
||||||
|
#define KEY_USERS "users"
|
||||||
|
#define KEY_USER "user"
|
||||||
|
#define KEY_NAME "name"
|
||||||
|
#define KEY_CERTIFICATE_AUTHORITY_DATA "certificate-authority-data"
|
||||||
|
#define KEY_SERVER "server"
|
||||||
|
#define KEY_CLIENT_CERTIFICATE_DATA "client-certificate-data"
|
||||||
|
#define KEY_CLIENT_KEY_DATA "client-key-data"
|
||||||
|
|
||||||
|
static int parse_kubeconfig_yaml_property_info_mapping(kubeconfig_property_t * property, yaml_document_t * document, yaml_node_t * node)
|
||||||
|
{
|
||||||
|
static char fname[] = "parse_kubeconfig_yaml_property_info_mapping()";
|
||||||
|
|
||||||
|
yaml_node_pair_t *pair = NULL;
|
||||||
|
yaml_node_t *key = NULL;
|
||||||
|
yaml_node_t *value = NULL;
|
||||||
|
|
||||||
|
for (pair = node->data.mapping.pairs.start; pair < node->data.mapping.pairs.top; pair++) {
|
||||||
|
key = yaml_document_get_node(document, pair->key);
|
||||||
|
value = yaml_document_get_node(document, pair->value);
|
||||||
|
|
||||||
|
if (key->type != YAML_SCALAR_NODE) {
|
||||||
|
fprintf(stderr, "%s: The key node is not YAML_SCALAR_NODE.\n", fname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value->type == YAML_SCALAR_NODE) {
|
||||||
|
if (KUBECONFIG_PROPERTY_TYPE_CLUSTER == property->type) {
|
||||||
|
if (0 == strcmp(key->data.scalar.value, KEY_CERTIFICATE_AUTHORITY_DATA)) {
|
||||||
|
property->certificate_authority_data = strdup(value->data.scalar.value);
|
||||||
|
} else if (0 == strcmp(key->data.scalar.value, KEY_SERVER)) {
|
||||||
|
property->server = strdup(value->data.scalar.value);
|
||||||
|
}
|
||||||
|
} else if (KUBECONFIG_PROPERTY_TYPE_USER == property->type) {
|
||||||
|
if (0 == strcmp(key->data.scalar.value, KEY_CLIENT_CERTIFICATE_DATA)) {
|
||||||
|
property->client_certificate_data = strdup(value->data.scalar.value);
|
||||||
|
} else if (0 == strcmp(key->data.scalar.value, KEY_CLIENT_KEY_DATA)) {
|
||||||
|
property->client_key_data = strdup(value->data.scalar.value);
|
||||||
|
}
|
||||||
|
} else if (KUBECONFIG_PROPERTY_TYPE_CONTEXT == property->type) {
|
||||||
|
if (0 == strcmp(key->data.scalar.value, KEY_CLUSTER)) {
|
||||||
|
property->cluster = strdup(value->data.scalar.value);
|
||||||
|
} else if (0 == strcmp(key->data.scalar.value, KEY_USER)) {
|
||||||
|
property->user = strdup(value->data.scalar.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_kubeconfig_yaml_property_mapping(kubeconfig_property_t * property, yaml_document_t * document, yaml_node_t * node)
|
||||||
|
{
|
||||||
|
static char fname[] = "parse_kubeconfig_yaml_property_mapping()";
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
yaml_node_pair_t *pair = NULL;
|
||||||
|
yaml_node_t *key = NULL;
|
||||||
|
yaml_node_t *value = NULL;
|
||||||
|
|
||||||
|
for (pair = node->data.mapping.pairs.start; pair < node->data.mapping.pairs.top; pair++) {
|
||||||
|
key = yaml_document_get_node(document, pair->key);
|
||||||
|
value = yaml_document_get_node(document, pair->value);
|
||||||
|
|
||||||
|
if (key->type != YAML_SCALAR_NODE) {
|
||||||
|
fprintf(stderr, "%s: The key node is not YAML_SCALAR_NODE.\n", fname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value->type == YAML_SCALAR_NODE) {
|
||||||
|
if (0 == strcmp(key->data.scalar.value, KEY_NAME)) {
|
||||||
|
property->name = strdup(value->data.scalar.value);
|
||||||
|
}
|
||||||
|
} else if (value->type == YAML_MAPPING_NODE) {
|
||||||
|
rc = parse_kubeconfig_yaml_property_info_mapping(property, document, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_kubeconfig_yaml_sequence(kubeconfig_property_t *** p_properties, int *p_properties_count, kubeconfig_property_type_t type, yaml_document_t * document, yaml_node_t * node)
|
||||||
|
{
|
||||||
|
yaml_node_item_t *item = NULL;
|
||||||
|
yaml_node_t *value = NULL;
|
||||||
|
int item_count = 0;
|
||||||
|
int i = 0;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
// Get the count of data (e.g. cluster, context, user)
|
||||||
|
for (item = node->data.sequence.items.start, item_count = 0; item < node->data.sequence.items.top; item++, item_count++) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
int properties_count = item_count;
|
||||||
|
kubeconfig_property_t **properties = kubeconfig_properties_create(properties_count, type);
|
||||||
|
if (!properties) {
|
||||||
|
fprintf(stderr, "Cannot allocate memory for kubeconfig properties.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (item = node->data.sequence.items.start, i = 0; item < node->data.sequence.items.top; item++, i++) {
|
||||||
|
value = yaml_document_get_node(document, *item);
|
||||||
|
rc = parse_kubeconfig_yaml_property_mapping(properties[i], document, value);
|
||||||
|
if (0 != rc) {
|
||||||
|
fprintf(stderr, "Cannot parse kubeconfi properties.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*p_properties = properties;
|
||||||
|
*p_properties_count = properties_count;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_kubeconfig_yaml_top_mapping(kubeconfig_t * kubeconfig, yaml_document_t * document, yaml_node_t * node)
|
||||||
|
{
|
||||||
|
static char fname[] = "parse_kubeconfig_yaml_top_mapping()";
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
yaml_node_pair_t *pair = NULL;
|
||||||
|
yaml_node_t *key = NULL;
|
||||||
|
yaml_node_t *value = NULL;
|
||||||
|
|
||||||
|
for (pair = node->data.mapping.pairs.start; pair < node->data.mapping.pairs.top; pair++) {
|
||||||
|
key = yaml_document_get_node(document, pair->key);
|
||||||
|
value = yaml_document_get_node(document, pair->value);
|
||||||
|
|
||||||
|
if (key->type != YAML_SCALAR_NODE) {
|
||||||
|
fprintf(stderr, "%s: The key node is not YAML_SCALAR_NODE.\n", fname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value->type == YAML_SCALAR_NODE) {
|
||||||
|
if (0 == strcmp(key->data.scalar.value, KEY_APIVERSION)) {
|
||||||
|
kubeconfig->apiVersion = strdup(value->data.scalar.value);
|
||||||
|
} else if (0 == strcmp(key->data.scalar.value, KEY_KIND)) {
|
||||||
|
kubeconfig->kind = strdup(value->data.scalar.value);
|
||||||
|
} else if (0 == strcmp(key->data.scalar.value, KEY_CURRENT_CONTEXT)) {
|
||||||
|
kubeconfig->current_context = strdup(value->data.scalar.value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (0 == strcmp(key->data.scalar.value, KEY_CLUSTERS)) {
|
||||||
|
rc = parse_kubeconfig_yaml_sequence(&(kubeconfig->clusters), &(kubeconfig->clusters_count), KUBECONFIG_PROPERTY_TYPE_CLUSTER, document, value);
|
||||||
|
} else if (0 == strcmp(key->data.scalar.value, KEY_CONTEXTS)) {
|
||||||
|
rc = parse_kubeconfig_yaml_sequence(&(kubeconfig->contexts), &(kubeconfig->contexts_count), KUBECONFIG_PROPERTY_TYPE_CONTEXT, document, value);
|
||||||
|
} else if (0 == strcmp(key->data.scalar.value, KEY_USERS)) {
|
||||||
|
rc = parse_kubeconfig_yaml_sequence(&(kubeconfig->users), &(kubeconfig->users_count), KUBECONFIG_PROPERTY_TYPE_USER, document, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_kubeconfig_yaml_node(kubeconfig_t * kubeconfig, yaml_document_t * document, yaml_node_t * node)
|
||||||
|
{
|
||||||
|
static char fname[] = "parse_kubeconfig_yaml_node()";
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (YAML_MAPPING_NODE == node->type) {
|
||||||
|
rc = parse_kubeconfig_yaml_top_mapping(kubeconfig, document, node);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "%s: %s is not a valid kubeconfig file.\n", fname, kubeconfig->fileName);
|
||||||
|
rc = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_kubeconfig_yaml_document(kubeconfig_t * kubeconfig, yaml_document_t * document)
|
||||||
|
{
|
||||||
|
static char fname[] = "parse_kubeconfig_yaml_document()";
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
yaml_node_t *root;
|
||||||
|
root = yaml_document_get_root_node(document);
|
||||||
|
if (NULL == root) {
|
||||||
|
fprintf(stderr, "%s: The document is null\n", fname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = parse_kubeconfig_yaml_node(kubeconfig, document, root);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int kubeyaml_load_kubeconfig(kubeconfig_t * kubeconfig)
|
||||||
|
{
|
||||||
|
static char fname[] = "kubeyaml_load_kubeconfig()";
|
||||||
|
|
||||||
|
yaml_parser_t parser;
|
||||||
|
yaml_document_t document;
|
||||||
|
|
||||||
|
int done = 0;
|
||||||
|
|
||||||
|
/* Create the Parser object. */
|
||||||
|
yaml_parser_initialize(&parser);
|
||||||
|
|
||||||
|
/* Set a file input. */
|
||||||
|
FILE *input = NULL;
|
||||||
|
if (kubeconfig->fileName) {
|
||||||
|
input = fopen(kubeconfig->fileName, "rb");
|
||||||
|
if (!input) {
|
||||||
|
fprintf(stderr, "%s: Cannot open the file %s.[%s]\n", fname, kubeconfig->fileName, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "%s: The kubeconf file name needs be set by kubeconfig->fileName .\n", fname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
yaml_parser_set_input_file(&parser, input);
|
||||||
|
|
||||||
|
while (!done) {
|
||||||
|
|
||||||
|
if (!yaml_parser_load(&parser, &document)) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
done = (!yaml_document_get_root_node(&document));
|
||||||
|
|
||||||
|
if (!done) {
|
||||||
|
parse_kubeconfig_yaml_document(kubeconfig, &document);
|
||||||
|
}
|
||||||
|
|
||||||
|
yaml_document_delete(&document);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cleanup */
|
||||||
|
yaml_parser_delete(&parser);
|
||||||
|
fclose(input);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
yaml_parser_delete(&parser);
|
||||||
|
fclose(input);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
37
kubernetes/config/kube_config_yaml.h
Normal file
37
kubernetes/config/kube_config_yaml.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#ifndef _KUBE_CONFIG_YAML_H
|
||||||
|
#define _KUBE_CONFIG_YAML_H
|
||||||
|
|
||||||
|
#include "kube_config_model.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* kubeyaml_load_kubeconfig
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
*
|
||||||
|
* Load the kubeconfig file specified by kubeconfig->fileName
|
||||||
|
* and get the kuberntes configuration for other fields of kubeconfig.
|
||||||
|
*
|
||||||
|
* Return:
|
||||||
|
*
|
||||||
|
* 0 Success
|
||||||
|
* -1 Failed
|
||||||
|
*
|
||||||
|
* Parameter:
|
||||||
|
*
|
||||||
|
* IN:
|
||||||
|
* kubeconfig->fileName: kubernetes cluster configuration file name
|
||||||
|
*
|
||||||
|
* OUT:
|
||||||
|
* kubeconfig: kubernetes cluster configuration
|
||||||
|
*/
|
||||||
|
int kubeyaml_load_kubeconfig(kubeconfig_t * kubeconfig);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
#endif /* _KUBE_CONFIG_YAML_H */
|
||||||
Reference in New Issue
Block a user