Merge pull request #10 from ityuhui/yhinclusterconfig

[Configuration]Support bearer tokens in cluster
This commit is contained in:
Kubernetes Prow Robot
2020-04-15 08:46:04 -07:00
committed by GitHub
8 changed files with 329 additions and 7 deletions

View File

@@ -15,14 +15,17 @@ void create_a_pod(apiClient_t * apiClient)
podinfo->spec = calloc(1, sizeof(v1_pod_spec_t));
podinfo->metadata = calloc(1, sizeof(v1_object_meta_t));
/* set pod name */
podinfo->metadata->name = strdup("test-pod-6");
/* set containers for pod */
list_t *containerlist = list_create();
v1_container_t *con = calloc(1, sizeof(v1_container_t));
con->name = strdup("my-container");
con->image = strdup("ubuntu:16.04");
con->image = strdup("ubuntu:latest");
con->image_pull_policy = strdup("IfNotPresent");
/* set command for container */
list_t *commandlist = list_create();
char *cmd = strdup("sleep");
list_addElement(commandlist, cmd);
@@ -33,9 +36,28 @@ void create_a_pod(apiClient_t * apiClient)
list_addElement(arglist, arg1);
con->args = arglist;
/* set volume mounts for container */
list_t *volumemounts = list_create();
v1_volume_mount_t *volmou = v1_volume_mount_create("/test", NULL, "test", 0, NULL, NULL);
list_addElement(volumemounts, volmou);
con->volume_mounts = volumemounts;
list_addElement(containerlist, con);
podinfo->spec->containers = containerlist;
/* set volumes for pod */
list_t *volumelist = list_create();
v1_volume_t *volume = calloc(1, sizeof(v1_volume_t));
volume->name = strdup("test");
v1_host_path_volume_source_t *hostPath = calloc(1, sizeof(v1_host_path_volume_source_t));
hostPath->path = strdup("/test");
volume->host_path = hostPath;
list_addElement(volumelist, volume);
podinfo->spec->volumes = volumelist;
/* call API in libkubernetes to create pod */
v1_pod_t *apod = CoreV1API_createNamespacedPod(apiClient, namespace, podinfo, NULL, NULL, NULL);
printf("code=%ld\n", apiClient->response_code);

View File

@@ -0,0 +1 @@
list_pod_incluster_bin

View File

@@ -0,0 +1,8 @@
INCLUDE:=-I../../kubernetes/include -I../../kubernetes/model -I../../kubernetes/api -I../../kubernetes/config
LIBS:=-L../../kubernetes/build -lkubernetes -lcurl -lyaml -lpthread -lssl -lz
CFLAGS:=-g
all:
gcc main.c $(CFLAGS) $(INCLUDE) $(LIBS) -o list_pod_incluster_bin
clean:
rm ./list_pod_incluster_bin

View File

@@ -0,0 +1,67 @@
#include <incluster_config.h>
#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 */
0, /* allowWatchBookmarks */
NULL, /* continue */
NULL, /* fieldSelector */
NULL, /* labelSelector */
0, /* limit */
NULL, /* resourceVersion */
0, /* timeoutSeconds */
0 /* 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);
}
} 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_incluster_config(&baseName, &sslConfig, &apiKeys);
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;
}

View File

@@ -24,6 +24,7 @@ set(SRCS
config/kube_config_model.c
config/kube_config_yaml.c
config/kube_config.c
config/incluster_config.c
src/list.c
src/apiKey.c
src/apiClient.c
@@ -778,6 +779,7 @@ set(HDRS
config/kube_config_model.h
config/kube_config_yaml.h
config/kube_config.h
config/incluster_config.h
include/apiClient.h
include/list.h
include/keyValuePair.h

View File

@@ -0,0 +1,167 @@
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <errno.h>
#include "incluster_config.h"
#define SERVICE_HOST_ENV_NAME "KUBERNETES_SERVICE_HOST"
#define SERVICE_PORT_ENV_NAME "KUBERNETES_SERVICE_PORT"
#define SERVICE_HTTPS_PREFIX "https://"
#define SERVICE_TOKEN_FILENAME "/var/run/secrets/kubernetes.io/serviceaccount/token"
#define SERVICE_CERT_FILENAME "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
#define AUTH_TOKEN_KEY "Authorization"
#define BEARER_TOKEN_TEMPLATE "Bearer %s"
#define BEARER_TOKEN_BUFFER_SIZE 1024
static int checkServiceAccountFile(const char *fileName)
{
static char fname[] = "checkServiceAccountFile()";
if (!fileName) {
fprintf(stderr, "%s: The file name must be specified.\n", fname);
return -1;
}
struct stat info;
if (-1 == stat(fileName, &info)) {
switch (errno) {
case ENOENT:
fprintf(stderr, "%s: The file %s does not exist.[%s]\n", fname, fileName, strerror(errno));
return -1;
case EACCES:
fprintf(stderr, "%s: No permission to read the file %s.[%s]\n", fname, fileName, strerror(errno));
return -1;
default:
fprintf(stderr, "%s: Cannot retrieve the information of file %s.[%s]\n", fname, fileName, strerror(errno));
return -1;
}
}
return 0;
}
static int setBasePathInCluster(char **pBasePath)
{
static char fname[] = "setBasePathInCluster()";
const char *service_host_env = secure_getenv(SERVICE_HOST_ENV_NAME);
if (!service_host_env) {
fprintf(stderr, "%s: Cannot retrieve the kubernetes service host inside a pod by the env %s.\n", fname, SERVICE_HOST_ENV_NAME);
return -1;
}
const char *service_port_env = secure_getenv(SERVICE_PORT_ENV_NAME);
if (!service_port_env) {
fprintf(stderr, "%s: Cannot retrieve the kubernetes service port inside a pod by the env %s.\n", fname, SERVICE_PORT_ENV_NAME);
return -1;
}
int basePathSize = strlen(SERVICE_HTTPS_PREFIX) + strlen(service_host_env) + strlen(service_port_env) + 2 /* 1 for ':', 1 for '\0' */ ;
char *basePath = calloc(basePathSize, sizeof(char));
if (!basePath) {
fprintf(stderr, "%s: Cannot allocate the memory for base path for kubernetes service.\n", fname);
return -1;
}
snprintf(basePath, basePathSize, "%s%s:%s", SERVICE_HTTPS_PREFIX, service_host_env, service_port_env);
*pBasePath = basePath;
return 0;
}
static int setSslConfigInCluster(sslConfig_t ** pSslConfig, const char *caFileName)
{
static char fname[] = "setSslConfigInCluster()";
if (0 != checkServiceAccountFile(caFileName)) {
fprintf(stderr, "%s: Cannot retrieve the CA for kubernetes service in the pod.\n", fname);
return -1;
}
sslConfig_t *sc = sslConfig_create(NULL, /* client certificate */
NULL, /* client private key */
caFileName, /* CA file */
0 /* 0 means the server certificate is required to be verified by CA */
);
if (!sc) {
return -1;
}
*pSslConfig = sc;
return 0;
}
static int readTokenInCluster(char *token, int token_buf_size)
{
static char fname[] = "readTokenInCluster()";
if (0 != checkServiceAccountFile(SERVICE_TOKEN_FILENAME)) {
fprintf(stderr, "%s: Cannot retrieve the token for kubernetes service in the pod.\n", fname);
return -1;
}
FILE *fp;
fp = fopen(SERVICE_TOKEN_FILENAME, "r");
if (NULL == fp) {
fprintf(stderr, "%s: Failed to open file %s.[%s]", fname, SERVICE_TOKEN_FILENAME, strerror(errno));
return -1;
}
char *read_str = fgets(token, token_buf_size, fp);
fclose(fp);
if (NULL == read_str) {
fprintf(stderr, "%s: Cannot read token from the file %s.[%s]", fname, SERVICE_TOKEN_FILENAME, strerror(errno));
return -1;
}
return 0;
}
static int setApiKeysInCluster(list_t ** pApiKeys)
{
static char fname[] = "setApiKeysInCluster()";
list_t *apiKeys = list_create();
if (!apiKeys) {
fprintf(stderr, "%s: Cannot allocate the memory for api kyes for kubernetes service.\n", fname);
return -1;
}
char token[BEARER_TOKEN_BUFFER_SIZE];
memset(token, 0, sizeof(token));
if (0 == readTokenInCluster(token, BEARER_TOKEN_BUFFER_SIZE)) {
char tokenValue[BEARER_TOKEN_BUFFER_SIZE];
memset(tokenValue, 0, sizeof(tokenValue));
snprintf(tokenValue, BEARER_TOKEN_BUFFER_SIZE, BEARER_TOKEN_TEMPLATE, token);
keyValuePair_t *keyPairToken = keyValuePair_create(strdup(AUTH_TOKEN_KEY), strdup(tokenValue));
list_addElement(apiKeys, keyPairToken);
} else {
fprintf(stderr, "%s: Cannot retrieve the service token in the pod.", fname);
return -1;
}
*pApiKeys = apiKeys;
return 0;
}
int load_incluster_config(char **pBasePath, sslConfig_t ** pSslConfig, list_t ** pApiKeys)
{
static char fname[] = "load_incluster_config()";
if (0 != setBasePathInCluster(pBasePath)) {
fprintf(stderr, "%s: Cannot set the base path for API server inside cluster.\n", fname);
return -1;
}
if (0 != setSslConfigInCluster(pSslConfig, SERVICE_CERT_FILENAME)) {
fprintf(stderr, "%s: Cannot set the SSL Configuration for the client inside cluster.\n", fname);
return -1;
}
if (0 != setApiKeysInCluster(pApiKeys)) {
fprintf(stderr, "%s: Cannot set the service tokens for the client inside cluster.\n", fname);
return -1;
}
return 0;
}

View File

@@ -0,0 +1,52 @@
#ifndef _INCLUSTER_CONFIG_H
#define _INCLUSTER_CONFIG_H
#include "../include/apiClient.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* load_incluster_config
*
*
* Description:
*
*
* Load kubernetes cluster configuration from service account
* files inside a pod
*
*
* Return:
*
* 0 Success
* -1 Failed
*
*
* Parameter:
*
*
* IN:
* None
*
*
* 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_incluster_config(char **pBasePath, sslConfig_t ** pSslConfig, list_t ** pApiKeys);
#ifdef __cplusplus
}
#endif
#endif /* _INCLUSTER_CONFIG_H */

View File

@@ -1,8 +1,10 @@
#include "kube_config.h"
#include "kube_config_yaml.h"
#define _GNU_SOURCE
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include "kube_config.h"
#include "kube_config_yaml.h"
#define ENV_KUBECONFIG "KUBECONFIG"
#define ENV_HOME "HOME"
@@ -137,15 +139,16 @@ static char *getWorkingConfigFile(const char *configFileNamePassedIn)
if (configFileNamePassedIn) {
configFileName = strdup(configFileNamePassedIn);
} else {
kubeconfig_env = getenv(ENV_KUBECONFIG);
kubeconfig_env = secure_getenv(ENV_KUBECONFIG);
if (kubeconfig_env) {
configFileName = strdup(kubeconfig_env);
} else {
homedir_env = getenv(ENV_HOME);
homedir_env = secure_getenv(ENV_HOME);
if (homedir_env) {
configFileName = calloc(strlen(homedir_env) + strlen(KUBE_CONFIG_DEFAULT_LOCATION) + 1, sizeof(char));
int configFileNameSize = strlen(homedir_env) + strlen(KUBE_CONFIG_DEFAULT_LOCATION) + 1;
configFileName = calloc(configFileNameSize, sizeof(char));
if (configFileName) {
sprintf(configFileName, KUBE_CONFIG_DEFAULT_LOCATION, homedir_env);
snprintf(configFileName, configFileNameSize, KUBE_CONFIG_DEFAULT_LOCATION, homedir_env);
}
}
}