diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-07-24 09:54:23 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-07-24 09:54:44 +0000 |
commit | 836b47cb7e99a977c5a23b059ca1d0b5065d310e (patch) | |
tree | 1604da8f482d02effa033c94a84be42bc0c848c3 /fluent-bit/src/flb_config_map.c | |
parent | Releasing debian version 1.44.3-2. (diff) | |
download | netdata-836b47cb7e99a977c5a23b059ca1d0b5065d310e.tar.xz netdata-836b47cb7e99a977c5a23b059ca1d0b5065d310e.zip |
Merging upstream version 1.46.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'fluent-bit/src/flb_config_map.c')
-rw-r--r-- | fluent-bit/src/flb_config_map.c | 817 |
1 files changed, 0 insertions, 817 deletions
diff --git a/fluent-bit/src/flb_config_map.c b/fluent-bit/src/flb_config_map.c deleted file mode 100644 index 9a3dd7ac..00000000 --- a/fluent-bit/src/flb_config_map.c +++ /dev/null @@ -1,817 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Fluent Bit - * ========== - * Copyright (C) 2015-2022 The Fluent Bit Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <fluent-bit/flb_info.h> -#include <fluent-bit/flb_kv.h> -#include <fluent-bit/flb_env.h> -#include <fluent-bit/flb_mem.h> -#include <fluent-bit/flb_log.h> -#include <fluent-bit/flb_utils.h> -#include <fluent-bit/flb_slist.h> -#include <fluent-bit/flb_macros.h> -#include <fluent-bit/flb_config_map.h> - -static int check_list_size(struct mk_list *list, int type) -{ - int len; - - len = mk_list_size(list); - if (type == FLB_CONFIG_MAP_SLIST_1 || type == FLB_CONFIG_MAP_CLIST_1) { - if (len < 1) { - return -1; - } - } - else if (type == FLB_CONFIG_MAP_SLIST_2 || type == FLB_CONFIG_MAP_CLIST_2) { - if (len < 2) { - return -1; - } - } - else if (type == FLB_CONFIG_MAP_SLIST_3 || type == FLB_CONFIG_MAP_CLIST_3) { - if (len < 3) { - return -1; - } - } - else if (type == FLB_CONFIG_MAP_SLIST_4 || type == FLB_CONFIG_MAP_CLIST_4) { - if (len < 4) { - return -1; - } - } - - return 0; -} - -/* - * Given a string, split the content using it proper separator generating a linked - * list of 'slist' - */ -static struct mk_list *parse_string_map_to_list(struct flb_config_map *map, char *str) -{ - int ret = -1; - int type; - int max_split = -1; - struct mk_list *list; - - type = map->type; - - /* Allocate list head */ - list = flb_malloc(sizeof(struct mk_list)); - if (!list) { - flb_errno(); - return NULL; - } - mk_list_init(list); - - /* Determinate the max split value based on it type */ - if (map->type > FLB_CONFIG_MAP_CLIST && map->type < FLB_CONFIG_MAP_SLIST) { - type = FLB_CONFIG_MAP_CLIST; - max_split = (map->type - FLB_CONFIG_MAP_CLIST); - } - else if (map->type > FLB_CONFIG_MAP_SLIST) { - type = FLB_CONFIG_MAP_SLIST; - max_split = (map->type - FLB_CONFIG_MAP_SLIST); - } - - if (type == FLB_CONFIG_MAP_CLIST) { - ret = flb_slist_split_string(list, str, ',', max_split); - } - else if (type == FLB_CONFIG_MAP_SLIST) { - ret = flb_slist_split_tokens(list, str, max_split); - } - - if (ret == -1) { - flb_error("[config map] error reading list of options"); - flb_free(list); - return NULL; - } - - return list; -} - -static int translate_default_value(struct flb_config_map *map, char *val) -{ - int ret; - struct flb_config_map_val *entry = NULL; - struct mk_list *list = NULL; - - /* Prepare contexts if the map allows multiple entries */ - if (map->flags & FLB_CONFIG_MAP_MULT) { - entry = flb_calloc(1, sizeof(struct flb_config_map_val)); - if (!entry) { - flb_errno(); - /* - * do not worry about 'list' allocation, it will be destroyed by the caller - * when it catches this error - */ - return -1; - } - } - else { - entry = &map->value; - } - - /* Based on specific data types, populate 'value' */ - if (map->type == FLB_CONFIG_MAP_STR) { - /* Duplicate string as a flb_sds_t */ - entry->val.str = flb_sds_create(val); - - /* Validate new memory allocation */ - if (!entry->val.str) { - goto error; - } - } - else if (map->type == FLB_CONFIG_MAP_STR_PREFIX) { - /* - * For prefixed string types we don't process them, just validate - * that no default value has been set. - */ - if (val) { - flb_error("[config map] invalid default value for prefixed string '%s'", - map->name); - goto error; - } - } - else if (map->type == FLB_CONFIG_MAP_BOOL) { - ret = flb_utils_bool(val); - if (ret == -1) { - flb_error("[config map] invalid default value for boolean '%s=%s'", - map->name, val); - goto error; - } - entry->val.boolean = flb_utils_bool(val); - } - else if (map->type == FLB_CONFIG_MAP_INT) { - entry->val.i_num = atoi(val); - } - else if (map->type == FLB_CONFIG_MAP_DOUBLE) { - entry->val.d_num = atof(val); - } - else if (map->type == FLB_CONFIG_MAP_SIZE) { - entry->val.s_num = flb_utils_size_to_bytes(val); - } - else if (map->type == FLB_CONFIG_MAP_TIME) { - entry->val.i_num = flb_utils_time_to_seconds(val); - } - else if (map->type >= FLB_CONFIG_MAP_CLIST && - map->type <= FLB_CONFIG_MAP_SLIST_4) { - - list = parse_string_map_to_list(map, val); - if (!list) { - flb_error("[config map] cannot parse list of values '%s'", val); - goto error; - } - - entry->val.list = list; - list = NULL; - } - - if (map->flags & FLB_CONFIG_MAP_MULT) { - mk_list_add(&entry->_head, map->value.mult); - } - - return 0; - - error: - if (map->flags & FLB_CONFIG_MAP_MULT) { - flb_free(entry); - } - return -1; -} - -static flb_sds_t helper_map_options(struct mk_list *map) -{ - flb_sds_t buf; - flb_sds_t tmp; - struct mk_list *head; - struct flb_config_map *m; - - buf = flb_sds_create_size(256); - if (!buf) { - flb_errno(); - return NULL; - } - - tmp = flb_sds_printf(&buf, "The following properties are allowed: "); - if (!tmp) { - flb_errno(); - flb_sds_destroy(buf); - return NULL; - } - buf = tmp; - - mk_list_foreach(head, map) { - m = mk_list_entry(head, struct flb_config_map, _head); - if (head->next != map) { - tmp = flb_sds_printf(&buf, "%s, ", m->name); - } - else { - if (mk_list_size(map) == 1) { - tmp = flb_sds_printf(&buf, "%s.", m->name); - } - else { - tmp = flb_sds_printf(&buf, "and %s.", m->name); - } - } - - if (!tmp) { - flb_errno(); - flb_sds_destroy(buf); - return NULL; - } - buf = tmp; - } - - return buf; -} - -/* - * Given a static plugin configuration map, create a linked list representation. We use a - * linked list using heap memory instead of the stack since a plugin can be loaded multiple - * times. - * - * In addition, for default values, we process them and populate the 'value' field with - * proper data types. - */ -struct mk_list *flb_config_map_create(struct flb_config *config, - struct flb_config_map *map) -{ - int ret; - flb_sds_t env; - struct mk_list *tmp; - struct mk_list *list; - struct flb_config_map *new = NULL; - struct flb_config_map *m; - - list = flb_malloc(sizeof(struct mk_list)); - if (!list) { - flb_errno(); - return NULL; - } - mk_list_init(list); - - /* - * Read every property defined in the config map and create a new dynamic list - * with the same content. - * - * As an additional step, it populate the 'value' field using the given default - * value if any. Note that default values are strings so they are processed - * to fit into the proper data type of 'value'. - */ - m = map; - while (m && m->name) { - /* Allocate map node */ - new = flb_calloc(1, sizeof(struct flb_config_map)); - if (!new) { - flb_errno(); - flb_config_map_destroy(list); - return NULL; - } - - new->type = m->type; - new->name = flb_sds_create(m->name); - if (new->name == NULL) { - flb_free(new); - flb_config_map_destroy(list); - return NULL; - } - - /* Translate default value */ - if (m->def_value) { - /* - * Before to translate any value, make sure to disable the warning - * about unused variables. This might happen if a default value is an - * environment variable and the user is not using it (which is ok for - * that specific use case). - */ - flb_env_warn_unused(config->env, FLB_FALSE); - - /* Translate the value */ - env = flb_env_var_translate(config->env, m->def_value); - if (env == NULL) { - flb_errno(); - flb_sds_destroy(new->name); - flb_free(new); - flb_config_map_destroy(list); - return NULL; - } - new->def_value = env; - flb_env_warn_unused(config->env, FLB_TRUE); - } - - new->flags = m->flags; - new->set_property = m->set_property; - new->offset = m->offset; - new->value.mult = NULL; - new->desc = m->desc; - mk_list_add(&new->_head, list); - - if (new->set_property == FLB_FALSE) { - m++; - continue; - } - - /* If this is a multiple type of entries, initialize the main list */ - if (new->flags & FLB_CONFIG_MAP_MULT) { - tmp = flb_malloc(sizeof(struct mk_list)); - if (!tmp) { - flb_errno(); - flb_config_map_destroy(list); - return NULL; - } - mk_list_init(tmp); - new->value.mult = tmp; - } - - /* - * If there is no default value or the entry will not be set, just - * continue with the next map entry - */ - if (!m->def_value) { - m++; - continue; - } - - /* Assign value based on data type and multiple mode if set */ - ret = translate_default_value(new, new->def_value); - if (ret == -1) { - flb_config_map_destroy(list); - return NULL; - } - m++; - } - - return list; -} - -static void destroy_map_val(int type, struct flb_config_map_val *value) -{ - if (type == FLB_CONFIG_MAP_STR && value->val.str) { - flb_sds_destroy(value->val.str); - } - else if ((type >= FLB_CONFIG_MAP_CLIST && - type <= FLB_CONFIG_MAP_SLIST_4) && - value->val.list) { - flb_slist_destroy(value->val.list); - flb_free(value->val.list); - } -} - -/* Destroy a config map context */ -void flb_config_map_destroy(struct mk_list *list) -{ - struct mk_list *tmp; - struct mk_list *head; - struct mk_list *v_head; - struct mk_list *v_tmp; - struct flb_config_map *map; - struct flb_config_map_val *entry; - - mk_list_foreach_safe(head, tmp, list) { - map = mk_list_entry(head, struct flb_config_map, _head); - mk_list_del(&map->_head); - - if (map->flags & FLB_CONFIG_MAP_MULT && map->value.mult) { - mk_list_foreach_safe(v_head, v_tmp, map->value.mult) { - entry = mk_list_entry(v_head, struct flb_config_map_val, _head); - mk_list_del(&entry->_head); - destroy_map_val(map->type, entry); - flb_free(entry); - } - flb_free(map->value.mult); - } - else { - destroy_map_val(map->type, &map->value); - } - if (map->def_value) { - flb_sds_destroy(map->def_value); - } - flb_sds_destroy(map->name); - flb_free(map); - } - flb_free(list); -} - -/* Count the number of times a property key exists */ -int property_count(char *key, int len, struct mk_list *properties) -{ - int count = 0; - struct mk_list *head; - struct flb_kv *kv; - - mk_list_foreach(head, properties) { - kv = mk_list_entry(head, struct flb_kv, _head); - if (flb_sds_len(kv->key) != len) { - continue; - } - - if (strncmp(kv->key, key, len) == 0) { - count++; - } - } - return count; -} - -/* - * If the property starts with '_debug.', it's an internal property for - * some component of Fluent Bit, not the plugin it self. - */ -static int is_internal_debug_property(char *prop_name) -{ -#ifdef FLB_HAVE_HTTP_CLIENT_DEBUG - if (strncmp(prop_name, "_debug.http.", 12) == 0) { - return FLB_TRUE; - } -#endif - - return FLB_FALSE; -} - - -/* Validate that the incoming properties set by the caller are allowed by the plugin */ -int flb_config_map_properties_check(char *context_name, - struct mk_list *in_properties, - struct mk_list *map) -{ - int len; - int found; - int count = 0; - int ret; - flb_sds_t helper; - struct flb_kv *kv; - struct mk_list *head; - struct mk_list *m_head; - struct flb_config_map *m; - - /* Iterate all incoming property list */ - mk_list_foreach(head, in_properties) { - kv = mk_list_entry(head, struct flb_kv, _head); - found = FLB_FALSE; - - - ret = is_internal_debug_property(kv->key); - if (ret == FLB_TRUE) { - /* Skip the config map */ - continue; - } - - if (strcasecmp(kv->key, "active") == 0) { - /* Accept 'active' property ... */ - continue; - } - - /* Lookup the key into the provided map */ - mk_list_foreach(m_head, map) { - m = mk_list_entry(m_head, struct flb_config_map, _head); - - len = flb_sds_len(m->name); - if (m->type != FLB_CONFIG_MAP_STR_PREFIX) { - if (len != flb_sds_len(kv->key)) { - continue; - } - } - - if (strncasecmp(kv->key, m->name, len) == 0) { - if (m->type == FLB_CONFIG_MAP_STR_PREFIX) { - if (flb_sds_len(kv->key) <= len) { - flb_error("[config] incomplete prefixed key '%s'", kv->key); - found = FLB_FALSE; - break; - } - } - else if(m->type == FLB_CONFIG_MAP_DEPRECATED) { - flb_warn("[config] %s: '%s' is deprecated", - context_name, kv->key); - } - found = FLB_TRUE; - break; - } - } - - if (found == FLB_FALSE) { - helper = helper_map_options(map); - if (!helper) { - flb_error("[config] %s: unknown configuration property '%s'", - context_name, kv->key); - } - else { - flb_error("[config] %s: unknown configuration property '%s'. %s", - context_name, kv->key, helper); - flb_sds_destroy(helper); - } - - return -1; - } - - /* Validate number of times the property is set */ - count = property_count(kv->key, flb_sds_len(kv->key), in_properties); - if ((m->flags & FLB_CONFIG_MAP_MULT) == 0) { - if (count > 1) { - flb_error("[config] %s: configuration property '%s' is set %i times", - context_name, kv->key, count); - return -1; - } - } - } - - return 0; -} - -/* - * Returns FLB_TRUE or FLB_FALSE if a property aims to override the default value - * assigned to the map key valled 'name'. - */ -static int properties_override_default(struct mk_list *properties, char *name) -{ - int len; - struct mk_list *head; - struct flb_kv *kv; - - len = strlen(name); - - mk_list_foreach(head, properties) { - kv = mk_list_entry(head, struct flb_kv, _head); - if (flb_sds_len(kv->key) != len) { - continue; - } - - if (strcasecmp(kv->key, name) == 0) { - return FLB_TRUE; - } - } - - return FLB_FALSE; -} - -/* - * Return the number of expected values if the property type is from CLIST - * or SLIST family. - */ -int flb_config_map_expected_values(int type) -{ - if (type > FLB_CONFIG_MAP_CLIST && type < FLB_CONFIG_MAP_SLIST) { - return type - FLB_CONFIG_MAP_CLIST; - } - if (type > FLB_CONFIG_MAP_SLIST && type <= FLB_CONFIG_MAP_SLIST_4) { - return type - FLB_CONFIG_MAP_SLIST; - } - return -1; -} - - -/* - * Function used by plugins that needs to populate their context structure with the - * configuration properties already mapped. - */ -int flb_config_map_set(struct mk_list *properties, struct mk_list *map, void *context) -{ - int ret; - int len; - char *base; - char *m_bool; - int *m_i_num; - double *m_d_num; - size_t *m_s_num; - flb_sds_t *m_str; - struct flb_kv *kv; - struct mk_list *head; - struct mk_list *m_head; - struct mk_list **m_list; - struct mk_list *list; - struct flb_config_map *m = NULL; - struct flb_config_map_val *entry = NULL; - - base = context; - - /* Link 'already processed default values' into the caller context */ - mk_list_foreach(m_head, map) { - m = mk_list_entry(m_head, struct flb_config_map, _head); - - /* - * If the map type allows multiple entries, the user context is a pointer - * for a linked list. We just point their structure to our pre-processed - * list of entries. - */ - if (m->flags & FLB_CONFIG_MAP_MULT && m->set_property == FLB_TRUE) { - m_list = (struct mk_list **) (base + m->offset); - *m_list = m->value.mult; - continue; - } - - /* - * If no default value exists or the map will not write to the user - * context.. skip it. - */ - if (!m->def_value || m->set_property == FLB_FALSE) { - continue; - } - - /* - * If a property set by the user will override the default value, just - * do not put the default value into the context since it will be replaced - * later. - */ - ret = properties_override_default(properties, m->name); - if (ret == FLB_TRUE) { - continue; - } - - /* All the following steps are direct writes to the user context */ - if (m->type == FLB_CONFIG_MAP_STR) { - m_str = (char **) (base + m->offset); - *m_str = m->value.val.str; - } - else if (m->type == FLB_CONFIG_MAP_INT) { - m_i_num = (int *) (base + m->offset); - *m_i_num = m->value.val.i_num; - } - else if (m->type == FLB_CONFIG_MAP_DOUBLE) { - m_d_num = (double *) (base + m->offset); - *m_d_num = m->value.val.d_num; - } - else if (m->type == FLB_CONFIG_MAP_SIZE) { - m_s_num = (size_t *) (base + m->offset); - *m_s_num = m->value.val.s_num; - } - else if (m->type == FLB_CONFIG_MAP_TIME) { - m_i_num = (int *) (base + m->offset); - *m_i_num = m->value.val.s_num; - } - else if (m->type == FLB_CONFIG_MAP_BOOL) { - m_bool = (char *) (base + m->offset); - *m_bool = m->value.val.boolean; - } - else if (m->type >= FLB_CONFIG_MAP_CLIST || - m->type <= FLB_CONFIG_MAP_SLIST_4) { - m_list = (struct mk_list **) (base + m->offset); - *m_list = m->value.val.list; - } - } - - /* - * Iterate all properties coming from the configuration reader. If a property overrides - * a default value already set in the previous step, just link to the new value. - */ - mk_list_foreach(head, properties) { - kv = mk_list_entry(head, struct flb_kv, _head); - if (kv->val == NULL) { - continue; - } - - mk_list_foreach(m_head, map) { - m = mk_list_entry(m_head, struct flb_config_map, _head); - if (flb_sds_len(kv->key) != flb_sds_len(m->name)) { - m = NULL; - continue; - } - - if (strncasecmp(kv->key, m->name, flb_sds_len(m->name)) == 0) { - break; - } - m = NULL; - continue; - - } - - if (!m || m->set_property == FLB_FALSE) { - continue; - } - - /* Check if the map allows multiple entries */ - if (m->flags & FLB_CONFIG_MAP_MULT) { - /* Create node */ - entry = flb_calloc(1, sizeof(struct flb_config_map_val)); - if (!entry) { - flb_errno(); - return -1; - } - - /* Populate value */ - if (m->type == FLB_CONFIG_MAP_STR) { - entry->val.str = flb_sds_create(kv->val); - } - else if (m->type == FLB_CONFIG_MAP_INT) { - entry->val.i_num = atoi(kv->val); - } - else if (m->type == FLB_CONFIG_MAP_DOUBLE) { - entry->val.d_num = atof(kv->val); - } - else if (m->type == FLB_CONFIG_MAP_SIZE) { - entry->val.s_num = flb_utils_size_to_bytes(kv->val); - } - else if (m->type == FLB_CONFIG_MAP_TIME) { - entry->val.i_num = flb_utils_time_to_seconds(kv->val); - } - else if (m->type == FLB_CONFIG_MAP_BOOL) { - ret = flb_utils_bool(kv->val); - if (ret == -1) { - flb_free(entry); - flb_error("[config map] invalid value for boolean property '%s=%s'", - m->name, kv->val); - return -1; - } - entry->val.boolean = ret; - } - else if (m->type >= FLB_CONFIG_MAP_CLIST || - m->type <= FLB_CONFIG_MAP_SLIST_4) { - - list = parse_string_map_to_list(m, kv->val); - if (!list) { - flb_error("[config map] cannot parse list of values '%s'", kv->val); - flb_free(entry); - return -1; - } - entry->val.list = list; - - /* Validate the number of entries are the minimum expected */ - len = mk_list_size(list); - ret = check_list_size(list, m->type); - if (ret == -1) { - flb_error("[config map] property '%s' expects %i values " - "(only %i were found)", - kv->key, - flb_config_map_expected_values(m->type), len); - /* - * Register the entry anyways, so on exit the resources will - * be released - */ - mk_list_add(&entry->_head, m->value.mult); - return -1; - } - } - - /* Add entry to the map 'mult' list tail */ - mk_list_add(&entry->_head, m->value.mult); - - /* Override user context */ - m_list = (struct mk_list **) (base + m->offset); - *m_list = m->value.mult; - } - else if (map != NULL) { - /* Direct write to user context */ - if (m->type == FLB_CONFIG_MAP_STR) { - m_str = (char **) (base + m->offset); - *m_str = kv->val; - } - else if (m->type == FLB_CONFIG_MAP_INT) { - m_i_num = (int *) (base + m->offset); - *m_i_num = atoi(kv->val); - } - else if (m->type == FLB_CONFIG_MAP_DOUBLE) { - m_d_num = (double *) (base + m->offset); - *m_d_num = atof(kv->val); - } - else if (m->type == FLB_CONFIG_MAP_BOOL) { - m_bool = (char *) (base + m->offset); - ret = flb_utils_bool(kv->val); - if (ret == -1) { - flb_error("[config map] invalid value for boolean property '%s=%s'", - m->name, kv->val); - return -1; - } - *m_bool = ret; - } - else if (m->type == FLB_CONFIG_MAP_SIZE) { - m_s_num = (size_t *) (base + m->offset); - *m_s_num = flb_utils_size_to_bytes(kv->val); - } - else if (m->type == FLB_CONFIG_MAP_TIME) { - m_i_num = (int *) (base + m->offset); - *m_i_num = flb_utils_time_to_seconds(kv->val); - } - else if (m->type >= FLB_CONFIG_MAP_CLIST || - m->type <= FLB_CONFIG_MAP_SLIST_4) { - list = parse_string_map_to_list(m, kv->val); - if (!list) { - flb_error("[config map] cannot parse list of values '%s'", kv->val); - flb_free(entry); - return -1; - } - - if (m->value.val.list) { - destroy_map_val(m->type, &m->value); - } - - m->value.val.list = list; - m_list = (struct mk_list **) (base + m->offset); - *m_list = m->value.val.list; - } - } - } - - return 0; -} |