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 2 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
53 changes: 43 additions & 10 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,48 @@ int load_kube_config(char **pBasePath, sslConfig_t ** pSslConfig, list_t ** pApi
}

end:
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 = kubeconfig_create();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that you delete this below, I think you can stack allocate this and pass the pointer via & below.

That will save a heap allocation and also be cleaner code.

Copy link
Contributor Author

@DanyT DanyT Jul 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be done but implies additional changes in kubeconfig_free() as this function will attempt to free the kubeconfig_t* itself. I can do a kubeconfig_free_static() if needed in order to keep the original api interface unchanged.

Please let me know your thoughts on this one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Meanwhile I added support to use both heap-based and stack-based allocated kubeconfig_t and a bit of documentation for these internal functions.

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

kubeconfig->fileName = getWorkingConfigFile(configFileName);

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

kubeconfig_free(kubeconfig);
kubeconfig = NULL;

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 = kubeconfig_create();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stack allocate here to, as above.

Copy link
Contributor Author

@DanyT DanyT Jul 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

kubeconfig->buffer = strdup(buffer);

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

kubeconfig_free(kubeconfig);
kubeconfig = NULL;

return rc;
}

Expand Down
38 changes: 38 additions & 0 deletions kubernetes/config/kube_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,44 @@ extern "C" {

int load_kube_config(char **pBasePath, sslConfig_t ** pSslConfig, list_t ** pApiKeys, const char *configFileName);

/*
* load_kube_config_buffer
*
*
* Description:
*
*
* Load kubernetes cluster configuration from specfied buffer
*
*
* Return:
*
* 0 Success
* -1 Failed
*
*
* Parameter:
*
*
* IN:

* buffer : kubernetes cluster configuration data
*
*
* 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_buffer(char **pBasePath, sslConfig_t ** pSslConfig, list_t ** pApiKeys, const char *buffer);

/*
* free_client_config
*
Expand Down
4 changes: 4 additions & 0 deletions kubernetes/config/kube_config_model.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,10 @@ void kubeconfig_free(kubeconfig_t * kubeconfig)
free(kubeconfig->fileName);
kubeconfig->fileName = NULL;
}
if (kubeconfig->buffer) {
free(kubeconfig->buffer);
kubeconfig->buffer = NULL;
}
if (kubeconfig->apiVersion) {
free(kubeconfig->apiVersion);
kubeconfig->apiVersion = NULL;
Expand Down
1 change: 1 addition & 0 deletions kubernetes/config/kube_config_model.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ extern "C" {

typedef struct kubeconfig_t {
char *fileName;
char *buffer;
char *apiVersion;
char *preferences;
char *kind;
Expand Down
25 changes: 19 additions & 6 deletions kubernetes/config/kube_config_yaml.c
Original file line number Diff line number Diff line change
Expand Up @@ -430,25 +430,34 @@ int kubeyaml_load_kubeconfig(kubeconfig_t * kubeconfig)
{
static char fname[] = "kubeyaml_load_kubeconfig()";

/* Set a file input. */
/* Set a file input or use the provided buffer. */
FILE *input = NULL;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a test here to verify that only one of fileName and buffer is non-null.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

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 {
}
else if (kubeconfig->buffer) {
ityuhui marked this conversation as resolved.
Show resolved Hide resolved
// Nothing to do here for now.
}
else {
fprintf(stderr, "%s: The kubeconf file name needs be set by kubeconfig->fileName .\n", fname);
return -1;
}

/* Create the Parser object. */
yaml_parser_t parser;
yaml_document_t document;

/* Create the Parser object. */
yaml_parser_initialize(&parser);
yaml_parser_set_input_file(&parser, input);
if (input) {
yaml_parser_set_input_file(&parser, input);
}
else {
yaml_parser_set_input_string(&parser, (const unsigned char*)kubeconfig->buffer, strlen(kubeconfig->buffer));
}

int done = 0;
while (!done) {
Expand All @@ -469,12 +478,16 @@ int kubeyaml_load_kubeconfig(kubeconfig_t * kubeconfig)

/* Cleanup */
yaml_parser_delete(&parser);
fclose(input);
if (input) {
fclose(input);
}
return 0;

error:
yaml_parser_delete(&parser);
fclose(input);
if (input) {
fclose(input);
}
return -1;
}

Expand Down
4 changes: 3 additions & 1 deletion kubernetes/config/kube_config_yaml.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ extern "C" {
*
* IN:
* kubeconfig->fileName: kubernetes cluster configuration file name
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe note that either one, but not both should be supplied?

Copy link
Contributor Author

@DanyT DanyT Jul 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added a more explicit note there. There was already a hint in the doc for kubeconfig->buffer.

  • IN:
  • kubeconfig->fileName: kubernetes cluster configuration file name
  • kubeconfig->buffer: kubernetes cluster configuration data; this is considered only if kubeconfig-> fileName is set to NULL
  • Note: One may use either kubeconfig->fileName or kubeconfig->buffer but not both at the same time.

*
* kubeconfig->buffer: kubernetes cluster configuration data; this is considered only if kubeconfig->fileName is set to NULL
*
* OUT:
* kubeconfig: kubernetes cluster configuration
*
*/
int kubeyaml_load_kubeconfig(kubeconfig_t * kubeconfig);


/*
* kubeyaml_parse_exec_crendential
*
Expand Down