|
27 | 27 | #include <fluent-bit/flb_input.h> |
28 | 28 | #include <fluent-bit/flb_filter.h> |
29 | 29 | #include <fluent-bit/flb_output.h> |
30 | | - |
| 30 | +#include <fluent-bit/flb_custom_plugin.h> |
| 31 | +#include <fluent-bit/flb_config.h> |
| 32 | +#include <fluent-bit/flb_config_map.h> |
| 33 | +#include <fluent-bit/flb_utils.h> |
31 | 34 | #include <fluent-bit/flb_hash.h> |
32 | 35 |
|
| 36 | +#include <fluent-bit/calyptia/calyptia_constants.h> |
| 37 | + |
33 | 38 | #include "calyptia.h" |
34 | 39 |
|
| 40 | +#define UUID_BUFFER_SIZE 38 /* Maximum length of UUID string + null terminator */ |
| 41 | + |
| 42 | +/* Function wrappers to enable mocking for unit test filesystem access */ |
| 43 | +int (*flb_access)(const char *pathname, int mode) = access; |
| 44 | +int (*flb_open)(const char *pathname, int flags, ...) = open; |
| 45 | +ssize_t (*flb_write)(int fd, const void *buf, size_t count) = write; |
| 46 | +int (*flb_close)(int fd) = close; |
| 47 | +int (*flb_utils_read_file_wrapper)(char *path, char **out_buf, size_t *out_size) = flb_utils_read_file; |
| 48 | + |
35 | 49 | /* |
36 | 50 | * Check if the key belongs to a sensitive data field, if so report it. We never |
37 | 51 | * share any sensitive data. |
@@ -217,16 +231,13 @@ int set_fleet_input_properties(struct calyptia *ctx, struct flb_input_instance * |
217 | 231 | flb_input_set_property(fleet, "api_key", ctx->api_key); |
218 | 232 | flb_input_set_property(fleet, "host", ctx->cloud_host); |
219 | 233 | flb_input_set_property(fleet, "port", ctx->cloud_port); |
| 234 | + flb_input_set_property(fleet, "config_dir", ctx->fleet_config_dir); |
220 | 235 |
|
221 | 236 | /* Set TLS properties */ |
222 | 237 | flb_input_set_property(fleet, "tls", ctx->cloud_tls == 1 ? "on" : "off"); |
223 | 238 | flb_input_set_property(fleet, "tls.verify", ctx->cloud_tls_verify == 1 ? "on" : "off"); |
224 | 239 |
|
225 | 240 | /* Optional configurations */ |
226 | | - if (ctx->fleet_config_dir) { |
227 | | - flb_input_set_property(fleet, "config_dir", ctx->fleet_config_dir); |
228 | | - } |
229 | | - |
230 | 241 | if (ctx->fleet_max_http_buffer_size) { |
231 | 242 | flb_input_set_property(fleet, "max_http_buffer_size", ctx->fleet_max_http_buffer_size); |
232 | 243 | } |
@@ -376,15 +387,182 @@ static flb_sds_t sha256_to_hex(unsigned char *sha256) |
376 | 387 | return hex; |
377 | 388 | } |
378 | 389 |
|
379 | | -static flb_sds_t get_machine_id(struct calyptia *ctx) |
| 390 | +static flb_sds_t generate_base_agent_directory(struct calyptia *ctx, flb_sds_t *fleet_dir) |
380 | 391 | { |
381 | | - int ret; |
382 | | - char *buf; |
383 | | - size_t blen; |
| 392 | + flb_sds_t ret = NULL; |
| 393 | + |
| 394 | + if (ctx == NULL || fleet_dir == NULL) { |
| 395 | + return NULL; |
| 396 | + } |
| 397 | + |
| 398 | + if (*fleet_dir == NULL) { |
| 399 | + *fleet_dir = flb_sds_create_size(CALYPTIA_MAX_DIR_SIZE); |
| 400 | + if (*fleet_dir == NULL) { |
| 401 | + return NULL; |
| 402 | + } |
| 403 | + } |
| 404 | + |
| 405 | + ret = flb_sds_printf(fleet_dir, "%s", ctx->fleet_config_dir); |
| 406 | + if (ret == NULL) { |
| 407 | + flb_sds_destroy(*fleet_dir); |
| 408 | + return NULL; |
| 409 | + } |
| 410 | + |
| 411 | + return ret; |
| 412 | +} |
| 413 | + |
| 414 | +flb_sds_t agent_config_filename(struct calyptia *ctx, char *fname) |
| 415 | +{ |
| 416 | + flb_sds_t cfgname = NULL; |
| 417 | + flb_sds_t ret; |
| 418 | + |
| 419 | + if (ctx == NULL || fname == NULL) { |
| 420 | + return NULL; |
| 421 | + } |
| 422 | + |
| 423 | + if (generate_base_agent_directory(ctx, &cfgname) == NULL) { |
| 424 | + return NULL; |
| 425 | + } |
| 426 | + |
| 427 | + ret = flb_sds_printf(&cfgname, PATH_SEPARATOR "%s.conf", fname); |
| 428 | + if (ret == NULL) { |
| 429 | + flb_sds_destroy(cfgname); |
| 430 | + return NULL; |
| 431 | + } |
| 432 | + |
| 433 | + return cfgname; |
| 434 | +} |
| 435 | + |
| 436 | +static char* generate_uuid() { |
| 437 | + char* uuid = flb_malloc(UUID_BUFFER_SIZE); |
| 438 | + if (!uuid) { |
| 439 | + flb_errno(); |
| 440 | + return NULL; |
| 441 | + } |
| 442 | + |
| 443 | + /* create new UUID for fleet */ |
| 444 | + if (flb_utils_uuid_v4_gen(uuid) != 0 || strlen(uuid) == 0) { |
| 445 | + flb_free(uuid); |
| 446 | + return NULL; |
| 447 | + } |
| 448 | + return uuid; |
| 449 | +} |
| 450 | + |
| 451 | +static int write_uuid_to_file(flb_sds_t fleet_machine_id, char* uuid) { |
| 452 | + int fd; |
| 453 | + size_t uuid_len; |
| 454 | + |
| 455 | + if (fleet_machine_id == NULL || uuid == NULL) { |
| 456 | + return FLB_FALSE; |
| 457 | + } |
| 458 | + |
| 459 | + /* write uuid to file */ |
| 460 | + fd = flb_open(fleet_machine_id, O_CREAT | O_WRONLY | O_TRUNC, 0666); |
| 461 | + if (fd == -1) { |
| 462 | + return FLB_FALSE; |
| 463 | + } |
| 464 | + |
| 465 | + uuid_len = strlen(uuid); |
| 466 | + |
| 467 | + if (flb_write(fd, uuid, uuid_len) != uuid_len) { |
| 468 | + flb_close(fd); |
| 469 | + return FLB_FALSE; |
| 470 | + } |
| 471 | + |
| 472 | + flb_close(fd); |
| 473 | + return FLB_TRUE; |
| 474 | +} |
| 475 | + |
| 476 | +static int create_agent_directory(struct calyptia *ctx) |
| 477 | +{ |
| 478 | + if( ctx == NULL ) { |
| 479 | + return -1; |
| 480 | + } |
| 481 | + |
| 482 | + /* If it exists just return */ |
| 483 | + if (access(ctx->fleet_config_dir, F_OK) == 0) { |
| 484 | + return 0; |
| 485 | + } |
| 486 | + |
| 487 | + /* Create the directory if it does not exist */ |
| 488 | + if (flb_utils_mkdir(ctx->fleet_config_dir, 0700) != 0) { |
| 489 | + flb_plg_error(ctx->ins, "failed to create directory: %s", ctx->fleet_config_dir); |
| 490 | + return -1; |
| 491 | + } |
| 492 | + |
| 493 | + return 0; |
| 494 | +} |
| 495 | + |
| 496 | +flb_sds_t get_machine_id(struct calyptia *ctx) |
| 497 | +{ |
| 498 | + int ret = -1; |
| 499 | + char *buf = NULL; |
| 500 | + size_t blen = 0; |
384 | 501 | unsigned char sha256_buf[64] = {0}; |
385 | 502 |
|
| 503 | +#if defined(FLB_SYSTEM_WINDOWS) |
386 | 504 | /* retrieve raw machine id */ |
387 | 505 | ret = flb_utils_get_machine_id(&buf, &blen); |
| 506 | +#else |
| 507 | + /* /etc/machine-id is not guaranteed to be unique so we generate one */ |
| 508 | + flb_sds_t fleet_machine_id = NULL; |
| 509 | + |
| 510 | + /** ensure we have the directory created */ |
| 511 | + if (create_agent_directory(ctx) != 0) { |
| 512 | + return NULL; |
| 513 | + } |
| 514 | + |
| 515 | + /** now get the agent filename */ |
| 516 | + fleet_machine_id = machine_id_fleet_config_filename(ctx); |
| 517 | + if (fleet_machine_id == NULL) { |
| 518 | + flb_plg_error(ctx->ins, "unable to allocate machine id file"); |
| 519 | + return NULL; |
| 520 | + } |
| 521 | + |
| 522 | + /* check if the file exists first, if it does not we generate a UUID */ |
| 523 | + if (flb_access(fleet_machine_id, F_OK) != 0) { |
| 524 | + |
| 525 | + /* create new UUID for fleet */ |
| 526 | + buf = generate_uuid(); |
| 527 | + if( buf == NULL ) { |
| 528 | + flb_plg_error(ctx->ins, "failed to create uuid for fleet machine id"); |
| 529 | + flb_sds_destroy(fleet_machine_id); |
| 530 | + return NULL; |
| 531 | + } |
| 532 | + flb_plg_info(ctx->ins, "generated UUID for machine ID: %s", buf); |
| 533 | + |
| 534 | + /* write uuid to file */ |
| 535 | + if (write_uuid_to_file(fleet_machine_id, buf ) != FLB_TRUE) { |
| 536 | + flb_plg_error(ctx->ins, "failed to write fleet machine id file: %s", fleet_machine_id); |
| 537 | + flb_free(buf); |
| 538 | + flb_sds_destroy(fleet_machine_id); |
| 539 | + return NULL; |
| 540 | + } |
| 541 | + |
| 542 | + flb_free(buf); |
| 543 | + buf = NULL; |
| 544 | + |
| 545 | + flb_plg_info(ctx->ins, "written machine ID to file: %s", fleet_machine_id); |
| 546 | + } |
| 547 | + |
| 548 | + /* now check file exists (it always should) and read from it */ |
| 549 | + if (flb_access(fleet_machine_id, F_OK) == 0) { |
| 550 | + ret = flb_utils_read_file_wrapper(fleet_machine_id, &buf, &blen); |
| 551 | + if (ret != 0) { |
| 552 | + flb_plg_error(ctx->ins, "failed to read fleet machine id file: %s", fleet_machine_id); |
| 553 | + flb_sds_destroy(fleet_machine_id); |
| 554 | + return NULL; |
| 555 | + } |
| 556 | + flb_plg_info(ctx->ins, "read UUID (%s) from file: %s", buf, fleet_machine_id); |
| 557 | + } |
| 558 | + else { /* fall back to machine-id */ |
| 559 | + flb_plg_warn(ctx->ins, "unable to get uuid from file (%s) so falling back to machine id", fleet_machine_id); |
| 560 | + ret = flb_utils_get_machine_id(&buf, &blen); |
| 561 | + } |
| 562 | + |
| 563 | + /* Clean up no longer required filename */ |
| 564 | + flb_sds_destroy(fleet_machine_id); |
| 565 | +#endif |
388 | 566 |
|
389 | 567 | if (ret == -1) { |
390 | 568 | flb_plg_error(ctx->ins, "could not obtain machine id"); |
@@ -520,13 +698,13 @@ static struct flb_config_map config_map[] = { |
520 | 698 | }, |
521 | 699 |
|
522 | 700 | { |
523 | | - FLB_CONFIG_MAP_STR, "calyptia_host", "cloud-api.calyptia.com", |
| 701 | + FLB_CONFIG_MAP_STR, "calyptia_host", DEFAULT_CALYPTIA_HOST, |
524 | 702 | 0, FLB_TRUE, offsetof(struct calyptia, cloud_host), |
525 | 703 | "" |
526 | 704 | }, |
527 | 705 |
|
528 | 706 | { |
529 | | - FLB_CONFIG_MAP_STR, "calyptia_port", "443", |
| 707 | + FLB_CONFIG_MAP_STR, "calyptia_port", DEFAULT_CALYPTIA_PORT, |
530 | 708 | 0, FLB_TRUE, offsetof(struct calyptia, cloud_port), |
531 | 709 | "" |
532 | 710 | }, |
@@ -559,7 +737,7 @@ static struct flb_config_map config_map[] = { |
559 | 737 | "Fleet id to be used when registering agent in a fleet" |
560 | 738 | }, |
561 | 739 | { |
562 | | - FLB_CONFIG_MAP_STR, "fleet.config_dir", NULL, |
| 740 | + FLB_CONFIG_MAP_STR, "fleet.config_dir", FLEET_DEFAULT_CONFIG_DIR, |
563 | 741 | 0, FLB_TRUE, offsetof(struct calyptia, fleet_config_dir), |
564 | 742 | "Base path for the configuration directory." |
565 | 743 | }, |
|
0 commit comments