Skip to content

Commit 3e96ec5

Browse files
Patcosmo0920
andauthored
calyptia: generate machine id for fleet agents (#9691)
* calyptia: generate machine id for fleet agents Signed-off-by: Patrick Stephens <pat@chronosphere.io> * calyptia: add missing include Signed-off-by: Patrick Stephens <pat@chronosphere.io> * calyptia: add missing include Signed-off-by: Patrick Stephens <pat@chronosphere.io> * tests: resolve conflicting definitions Signed-off-by: Patrick Stephens <pat@chronosphere.io> * calyptia: resolve missing bool type Signed-off-by: Patrick Stephens <pat@chronosphere.io> * calyptia: resolve missing header Signed-off-by: Patrick Stephens <pat@chronosphere.io> * calyptia: resolve duplicate symbols for tests Signed-off-by: Patrick Stephens <pat@chronosphere.io> * calyptia: resolve function pointer usage Signed-off-by: Patrick Stephens <pat@chronosphere.io> * calyptia: update codeowners Signed-off-by: Patrick Stephens <pat@chronosphere.io> * custom_calyptia: tests: Add missing declarations To link those missing declaration functions, we need to define for stub in the custom_calyptia testing files. Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io> * custom_calyptia: Remove duplicated function declarations Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io> * tests: add calyptia machine id generation tests Signed-off-by: Patrick Stephens <pat@chronosphere.io> * tests: add missing header Signed-off-by: Patrick Stephens <pat@chronosphere.io> * tests: fix typos Signed-off-by: Patrick Stephens <pat@chronosphere.io> * tests: fix typos Signed-off-by: Patrick Stephens <pat@chronosphere.io> * tests: fix memory issues Signed-off-by: Patrick Stephens <pat@chronosphere.io> * tests: fix location Signed-off-by: Patrick Stephens <pat@chronosphere.io> * tests: fix destroy usage Signed-off-by: Patrick Stephens <pat@chronosphere.io> * tests: fix destroy usage Signed-off-by: Patrick Stephens <pat@chronosphere.io> --------- Signed-off-by: Patrick Stephens <pat@chronosphere.io> Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io> Co-authored-by: Hiroshi Hatake <hiroshi@chronosphere.io>
1 parent 9acc096 commit 3e96ec5

File tree

14 files changed

+489
-140
lines changed

14 files changed

+489
-140
lines changed

CODEOWNERS

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@
9191
# Devcontainer
9292
/.devcontainer @patrick-stephens @niedbalski @edsiper
9393

94-
# Calytia Fleet
95-
/plugins/custom_calyptia/ @pwhelan
96-
/plugins/in_calyptia_fleet/ @pwhelan
94+
# Calyptia Fleet
95+
/include/fluent-bit/calyptia/ @pwhelan @patrick-stephens @niedbalski
96+
/plugins/custom_calyptia/ @pwhelan @patrick-stephens @niedbalski
97+
/plugins/custom_calyptia/ @pwhelan @patrick-stephens @niedbalski
98+
/plugins/out_calyptia/ @pwhelan @patrick-stephens @niedbalski

Vagrantfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Vagrant.configure("2") do |config|
2828
# Main build
2929
apt-get install --yes build-essential cmake dh-make git make openssl pkg-config tar
3030
# Dependencies
31-
apt-get install --yes libssl3 libssl-dev libsasl2-dev pkg-config libsystemd-dev zlib1g-dev libpq-dev postgresql-server-dev-all flex bison libyaml-dev libpq5
31+
apt-get install --yes libssl3 libssl-dev libsasl2-dev pkg-config libsystemd-dev zlib1g-dev libpq-dev postgresql-server-dev-all flex bison libyaml-dev libpq5 libbpf-dev
3232
3333
# Debug
3434
apt-get install --yes gdb valgrind

include/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ install(FILES ${headers}
1010
COMPONENT headers
1111
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
1212

13+
file(GLOB headers "fluent-bit/calyptia/*.h")
14+
install(FILES ${headers}
15+
DESTINATION ${FLB_INSTALL_INCLUDEDIR}/fluent-bit
16+
COMPONENT headers
17+
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
18+
1319
file(GLOB headers "fluent-bit/config_format/*.h")
1420
install(FILES ${headers}
1521
DESTINATION ${FLB_INSTALL_INCLUDEDIR}/fluent-bit/config_format/
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2+
3+
/* Fluent Bit
4+
* ==========
5+
* Copyright (C) 2015-2024 The Fluent Bit Authors
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
#ifndef FLB_CALYPTIA_CONSTANTS_H
20+
#define FLB_CALYPTIA_CONSTANTS_H
21+
22+
/* End point */
23+
#define DEFAULT_CALYPTIA_HOST "cloud-api.calyptia.com"
24+
#define DEFAULT_CALYPTIA_PORT "443"
25+
26+
/* HTTP action types */
27+
#define CALYPTIA_ACTION_REGISTER 0
28+
#define CALYPTIA_ACTION_PATCH 1
29+
#define CALYPTIA_ACTION_METRICS 2
30+
#define CALYPTIA_ACTION_TRACE 3
31+
32+
/* Endpoints */
33+
#define CALYPTIA_ENDPOINT_CREATE "/v1/agents"
34+
#define CALYPTIA_ENDPOINT_PATCH "/v1/agents/%s"
35+
#define CALYPTIA_ENDPOINT_METRICS "/v1/agents/%s/metrics"
36+
#define CALYPTIA_ENDPOINT_TRACE "/v1/traces/%s"
37+
38+
#define CALYPTIA_ENDPOINT_FLEETS "/v1/fleets"
39+
#define CALYPTIA_ENDPOINT_FLEET_CONFIG_INI "/v1/fleets/%s/config?format=ini"
40+
#define CALYPTIA_ENDPOINT_FLEET_FILES "/v1/fleets/%s/files"
41+
42+
/* Storage */
43+
#define CALYPTIA_SESSION_FILE "session.CALYPTIA"
44+
45+
/* Headers */
46+
#define CALYPTIA_HEADERS_PROJECT "X-Project-Token"
47+
#define CALYPTIA_HEADERS_AGENT_TOKEN "X-Agent-Token"
48+
#define CALYPTIA_HEADERS_CTYPE "Content-Type"
49+
#define CALYPTIA_HEADERS_CTYPE_JSON "application/json"
50+
#define CALYPTIA_HEADERS_CTYPE_MSGPACK "application/x-msgpack"
51+
52+
#ifndef FLB_SYSTEM_WINDOWS
53+
#define FLEET_DEFAULT_CONFIG_DIR "/tmp/calyptia-fleet"
54+
#else
55+
#define FLEET_DEFAULT_CONFIG_DIR NULL
56+
#endif
57+
58+
#ifndef PATH_SEPARATOR
59+
#ifndef FLB_SYSTEM_WINDOWS
60+
#define PATH_SEPARATOR "/"
61+
#else
62+
#define PATH_SEPARATOR "\\"
63+
#endif
64+
#endif /* PATH_SEPARATOR */
65+
66+
#define CALYPTIA_MAX_DIR_SIZE 4096
67+
68+
#endif /* FLB_CALYPTIA_CONSTANTS_H */

include/fluent-bit/flb_utils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,5 +74,6 @@ int flb_utils_get_machine_id(char **out_id, size_t *out_size);
7474
void flb_utils_set_plugin_string_property(const char *name,
7575
flb_sds_t *field_storage,
7676
flb_sds_t new_value);
77+
int flb_utils_mkdir(const char *dir, int perms);
7778

7879
#endif

lib/cprofiles/include/cprofiles/cprof_info.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,9 @@
2020
#ifndef CPROF_INFO_H
2121
#define CPROF_INFO_H
2222

23-
#define CPROF_SOURCE_DIR "/Users/leonardo/Work/Calyptia/fluent-bit"
23+
#define CPROF_SOURCE_DIR "/src/fluent-bit"
2424

2525
/* General flags set by /CMakeLists.txt */
26-
#ifndef CPROF_HAVE_SANITIZE_ADDRESS
27-
#define CPROF_HAVE_SANITIZE_ADDRESS
28-
#endif
2926
#ifndef CPROF_HAVE_TIMESPEC_GET
3027
#define CPROF_HAVE_TIMESPEC_GET
3128
#endif

plugins/custom_calyptia/calyptia.c

Lines changed: 190 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,25 @@
2727
#include <fluent-bit/flb_input.h>
2828
#include <fluent-bit/flb_filter.h>
2929
#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>
3134
#include <fluent-bit/flb_hash.h>
3235

36+
#include <fluent-bit/calyptia/calyptia_constants.h>
37+
3338
#include "calyptia.h"
3439

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+
3549
/*
3650
* Check if the key belongs to a sensitive data field, if so report it. We never
3751
* share any sensitive data.
@@ -217,16 +231,13 @@ int set_fleet_input_properties(struct calyptia *ctx, struct flb_input_instance *
217231
flb_input_set_property(fleet, "api_key", ctx->api_key);
218232
flb_input_set_property(fleet, "host", ctx->cloud_host);
219233
flb_input_set_property(fleet, "port", ctx->cloud_port);
234+
flb_input_set_property(fleet, "config_dir", ctx->fleet_config_dir);
220235

221236
/* Set TLS properties */
222237
flb_input_set_property(fleet, "tls", ctx->cloud_tls == 1 ? "on" : "off");
223238
flb_input_set_property(fleet, "tls.verify", ctx->cloud_tls_verify == 1 ? "on" : "off");
224239

225240
/* Optional configurations */
226-
if (ctx->fleet_config_dir) {
227-
flb_input_set_property(fleet, "config_dir", ctx->fleet_config_dir);
228-
}
229-
230241
if (ctx->fleet_max_http_buffer_size) {
231242
flb_input_set_property(fleet, "max_http_buffer_size", ctx->fleet_max_http_buffer_size);
232243
}
@@ -376,15 +387,182 @@ static flb_sds_t sha256_to_hex(unsigned char *sha256)
376387
return hex;
377388
}
378389

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)
380391
{
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;
384501
unsigned char sha256_buf[64] = {0};
385502

503+
#if defined(FLB_SYSTEM_WINDOWS)
386504
/* retrieve raw machine id */
387505
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
388566

389567
if (ret == -1) {
390568
flb_plg_error(ctx->ins, "could not obtain machine id");
@@ -520,13 +698,13 @@ static struct flb_config_map config_map[] = {
520698
},
521699

522700
{
523-
FLB_CONFIG_MAP_STR, "calyptia_host", "cloud-api.calyptia.com",
701+
FLB_CONFIG_MAP_STR, "calyptia_host", DEFAULT_CALYPTIA_HOST,
524702
0, FLB_TRUE, offsetof(struct calyptia, cloud_host),
525703
""
526704
},
527705

528706
{
529-
FLB_CONFIG_MAP_STR, "calyptia_port", "443",
707+
FLB_CONFIG_MAP_STR, "calyptia_port", DEFAULT_CALYPTIA_PORT,
530708
0, FLB_TRUE, offsetof(struct calyptia, cloud_port),
531709
""
532710
},
@@ -559,7 +737,7 @@ static struct flb_config_map config_map[] = {
559737
"Fleet id to be used when registering agent in a fleet"
560738
},
561739
{
562-
FLB_CONFIG_MAP_STR, "fleet.config_dir", NULL,
740+
FLB_CONFIG_MAP_STR, "fleet.config_dir", FLEET_DEFAULT_CONFIG_DIR,
563741
0, FLB_TRUE, offsetof(struct calyptia, fleet_config_dir),
564742
"Base path for the configuration directory."
565743
},

0 commit comments

Comments
 (0)