Agent claiming (#7525)
Initial infrastructure support for agent claiming. This feature is not currently enabled as we are still finalizing the details of the cloud infrastructure w.r.t. agent claiming. The feature will be enabled when we are ready to release it.
This commit is contained in:
parent
c1436efd00
commit
ce9f70d7b3
|
@ -116,6 +116,7 @@ daemon/anonymous-statistics.sh
|
|||
daemon/get-kubernetes-labels.sh
|
||||
|
||||
health/notifications/alarm-notify.sh
|
||||
claim/netdata-claim.sh
|
||||
collectors/cgroups.plugin/cgroup-name.sh
|
||||
collectors/tc.plugin/tc-qos-helper.sh
|
||||
collectors/charts.d.plugin/charts.d.plugin
|
||||
|
|
1
BUILD.md
1
BUILD.md
|
@ -1,4 +1,3 @@
|
|||
|
||||
# The build system
|
||||
|
||||
We are currently migrating from `autotools` to `CMake` as a build-system. This document
|
||||
|
|
|
@ -601,6 +601,11 @@ set(BACKENDS_PLUGIN_FILES
|
|||
backends/prometheus/backend_prometheus.h
|
||||
)
|
||||
|
||||
set(CLAIM_PLUGIN_FILES
|
||||
claim/claim.c
|
||||
claim/claim.h
|
||||
)
|
||||
|
||||
set(EXPORTING_ENGINE_FILES
|
||||
exporting/exporting_engine.c
|
||||
exporting/exporting_engine.h
|
||||
|
@ -667,6 +672,7 @@ set(NETDATA_FILES
|
|||
${STATSD_PLUGIN_FILES}
|
||||
${STREAMING_PLUGIN_FILES}
|
||||
${WEB_PLUGIN_FILES}
|
||||
${CLAIM_PLUGIN_FILES}
|
||||
)
|
||||
|
||||
set(NETDATACLI_FILES
|
||||
|
|
|
@ -99,6 +99,7 @@ SUBDIRS += \
|
|||
registry \
|
||||
streaming \
|
||||
web \
|
||||
claim \
|
||||
$(NULL)
|
||||
|
||||
|
||||
|
@ -454,6 +455,11 @@ BACKENDS_PLUGIN_FILES = \
|
|||
backends/prometheus/backend_prometheus.h \
|
||||
$(NULL)
|
||||
|
||||
CLAIM_PLUGIN_FILES = \
|
||||
claim/claim.c \
|
||||
claim/claim.h \
|
||||
$(NULL)
|
||||
|
||||
EXPORTING_ENGINE_FILES = \
|
||||
exporting/exporting_engine.c \
|
||||
exporting/exporting_engine.h \
|
||||
|
@ -521,6 +527,7 @@ NETDATA_FILES = \
|
|||
$(STREAMING_PLUGIN_FILES) \
|
||||
$(STATSD_PLUGIN_FILES) \
|
||||
$(WEB_PLUGIN_FILES) \
|
||||
$(CLAIM_PLUGIN_FILES) \
|
||||
$(NULL)
|
||||
|
||||
if FREEBSD
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
AUTOMAKE_OPTIONS = subdir-objects
|
||||
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
|
||||
|
||||
CLEANFILES = \
|
||||
netdata-claim.sh \
|
||||
$(NULL)
|
||||
|
||||
include $(top_srcdir)/build/subst.inc
|
||||
SUFFIXES = .in
|
||||
|
||||
sbin_SCRIPTS = \
|
||||
netdata-claim.sh \
|
||||
$(NULL)
|
||||
|
||||
dist_noinst_DATA = \
|
||||
netdata-claim.sh.in \
|
||||
README.md \
|
||||
$(NULL)
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
# Agent claiming
|
||||
|
||||
Agent claiming is part of the onboarding process when creating a workspace in Netdata Cloud. Each workspace gets its own
|
||||
common invitation mechanism, which begins with the administrators of the workspace creating a **claiming-token**. They,
|
||||
or other users is their organization, can then use the claiming-token to add an agent to their workspace.
|
||||
|
||||
To claim a Netdata agent, you first send a claiming request to Netdata Cloud (from the agent node). Once the
|
||||
Netdata Cloud validates the claiming request of the agent (based on the claiming token), and returns a successful
|
||||
result, the node is considered claimed.
|
||||
|
||||
## Claiming script
|
||||
|
||||
The user can claim an agent by directly calling the `netdata-claim.sh` script **as the netdata user** and passing the
|
||||
following arguments:
|
||||
|
||||
```sh
|
||||
-token=TOKEN
|
||||
where TOKEN is the workspace claiming-token.
|
||||
-rooms=ROOM1,ROOM2,...
|
||||
where ROOMX is the workspace war-room to join. This list is optional.
|
||||
-url=URL_BASE
|
||||
where URL_BASE is the Netdata Cloud endpoint base URL. By default, this is https://netdata.cloud.
|
||||
-id=AGENT_ID
|
||||
where AGENT_ID is the unique identifier of the agent. This is the agent's MACHINE_GUID by default.
|
||||
-hostname=HOSTNAME
|
||||
where HOSTNAME is the result of the hostname command by default.
|
||||
```
|
||||
|
||||
For example, the following command claims an agent and adds it to rooms `room1` and `room2`:
|
||||
|
||||
```sh
|
||||
netdata-claim.sh -token=MYTOKEN1234567 -rooms=room1,room2
|
||||
```
|
||||
|
||||
You should then update the `netdata` service about the result with `netdatacli`:
|
||||
|
||||
```sh
|
||||
netdatacli reload-claiming-state
|
||||
```
|
||||
|
||||
This reloads the agent claiming state from disk.
|
||||
|
||||
## Netdata agent command line
|
||||
|
||||
The user can trigger agent claiming by calling the `netdata` service binary with the additional command line parameters:
|
||||
|
||||
```sh
|
||||
-W "claim -token=TOKEN -rooms=ROOM1,ROOM2"
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```sh
|
||||
/usr/sbin/netdata -D -W "claim -token=MYTOKEN1234567 -rooms=room1,room2"
|
||||
```
|
||||
|
||||
If need be, the user can override the agent's defaults by providing additional arguments like those described
|
||||
[here](#claiming-script).
|
||||
|
||||
## Claiming directory
|
||||
|
||||
Netdata stores the agent claiming-related state in the user configuration directory under `claim.d`, e.g. in
|
||||
`/etc/netdata/claim.d`. The user can put files in this directory to provide defaults to the `-token` and `-rooms`
|
||||
arguments. These files should be owned **by the `netdata` user**.
|
||||
|
||||
The `claim.d/token` file should contain the claiming-token and the `claim.d/rooms` file should contain the list of
|
||||
war-rooms.
|
||||
|
||||
The user can also put the Cloud endpoint's full certificate chain in `claim.d/cloud_fullchain.pem` so that the agent
|
||||
can trust the endpoint if necessary.
|
||||
|
||||
[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fclaim%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)](<>)
|
|
@ -0,0 +1,103 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "claim.h"
|
||||
#include "../registry/registry_internals.h"
|
||||
|
||||
char *claiming_pending_arguments = NULL;
|
||||
|
||||
static char *claiming_errors[] = {
|
||||
"Agent claimed successfully", // 0
|
||||
"Unknown argument", // 1
|
||||
"Problems with claiming working directory", // 2
|
||||
"Missing dependencies", // 3
|
||||
"Failure to connect to endpoint", // 4
|
||||
"Unknown HTTP error message", // 5
|
||||
"invalid agent id", // 6
|
||||
"invalid public key", // 7
|
||||
"token has expired", // 8
|
||||
"invalid token", // 9
|
||||
"duplicate agent id", // 10
|
||||
"claimed in another workspace", // 11
|
||||
"internal server error" // 12
|
||||
};
|
||||
|
||||
#define AGENT_UNCLAIMED 0
|
||||
#define AGENT_CLAIMED 1
|
||||
static uint8_t claiming_status = AGENT_UNCLAIMED;
|
||||
|
||||
uint8_t is_agent_claimed(void)
|
||||
{
|
||||
return (AGENT_CLAIMED == claiming_status);
|
||||
}
|
||||
|
||||
#define CLAIMING_COMMAND_LENGTH 16384
|
||||
|
||||
extern struct registry registry;
|
||||
|
||||
/* rrd_init() must have been called before this function */
|
||||
void claim_agent(char *claiming_arguments)
|
||||
{
|
||||
info("The claiming feature is under development and still subject to change before the next release");
|
||||
return;
|
||||
|
||||
int exit_code;
|
||||
pid_t command_pid;
|
||||
char command_buffer[CLAIMING_COMMAND_LENGTH + 1];
|
||||
FILE *fp;
|
||||
|
||||
snprintfz(command_buffer,
|
||||
CLAIMING_COMMAND_LENGTH,
|
||||
"exec netdata-claim.sh -hostname=%s -id=%s -url=%s %s",
|
||||
netdata_configured_hostname,
|
||||
localhost->machine_guid,
|
||||
registry.cloud_base_url,
|
||||
claiming_arguments);
|
||||
|
||||
info("Executing agent claiming command 'netdata-claim.sh'");
|
||||
fp = mypopen(command_buffer, &command_pid);
|
||||
if(!fp) {
|
||||
error("Cannot popen(\"%s\").", command_buffer);
|
||||
return;
|
||||
}
|
||||
info("Waiting for claiming command to finish.");
|
||||
while (fgets(command_buffer, CLAIMING_COMMAND_LENGTH, fp) != NULL) {;}
|
||||
exit_code = mypclose(fp, command_pid);
|
||||
info("Agent claiming command returned with code %d", exit_code);
|
||||
if (0 == exit_code) {
|
||||
claiming_status = AGENT_CLAIMED;
|
||||
info("Agent successfully claimed.");
|
||||
return;
|
||||
}
|
||||
if (exit_code < 0) {
|
||||
error("Agent claiming command failed to complete its run.");
|
||||
return;
|
||||
}
|
||||
errno = 0;
|
||||
unsigned maximum_known_exit_code = sizeof(claiming_errors) / sizeof(claiming_errors[0]);
|
||||
|
||||
if ((unsigned)exit_code > maximum_known_exit_code) {
|
||||
error("Agent failed to be claimed with an unknown error.");
|
||||
return;
|
||||
}
|
||||
error("Agent failed to be claimed with the following error message:");
|
||||
error("\"%s\"", claiming_errors[exit_code]);
|
||||
}
|
||||
|
||||
void load_claiming_state(void)
|
||||
{
|
||||
info("The claiming feature is under development and still subject to change before the next release");
|
||||
return;
|
||||
|
||||
char filename[FILENAME_MAX + 1];
|
||||
struct stat statbuf;
|
||||
|
||||
snprintfz(filename, FILENAME_MAX, "%s/claim.d/is_claimed", netdata_configured_user_config_dir);
|
||||
// check if the file exists
|
||||
if (lstat(filename, &statbuf) != 0) {
|
||||
info("File '%s' was not found. Setting state to AGENT_UNCLAIMED.", filename);
|
||||
claiming_status = AGENT_UNCLAIMED;
|
||||
} else {
|
||||
info("File '%s' was found. Setting state to AGENT_CLAIMED.", filename);
|
||||
claiming_status = AGENT_CLAIMED;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#ifndef NETDATA_CLAIM_H
|
||||
#define NETDATA_CLAIM_H 1
|
||||
|
||||
#include "../daemon/common.h"
|
||||
|
||||
extern char *claiming_pending_arguments;
|
||||
|
||||
void claim_agent(char *claiming_arguments);
|
||||
uint8_t is_agent_claimed(void);
|
||||
void load_claiming_state(void);
|
||||
|
||||
#endif //NETDATA_CLAIM_H
|
|
@ -0,0 +1,216 @@
|
|||
#!/usr/bin/env bash
|
||||
# netdata
|
||||
# real-time performance and health monitoring, done right!
|
||||
# (C) 2017 Costa Tsaousis <costa@tsaousis.gr>
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
# Exit code: 0 - Success
|
||||
# Exit code: 1 - Unknown argument
|
||||
# Exit code: 2 - Problems with claiming working directory
|
||||
# Exit code: 3 - Missing dependencies
|
||||
# Exit code: 4 - Failure to connect to endpoint
|
||||
# Exit code: 5 - Unknown HTTP error message
|
||||
#
|
||||
# OK: Agent claimed successfully
|
||||
# HTTP Status code: 200
|
||||
# Exit code: 0
|
||||
#
|
||||
# Error: The agent id is invalid; it does not fulfill the constraints
|
||||
# HTTP Status code: 422
|
||||
# Error message: "invalid agent id"
|
||||
# Exit code: 6
|
||||
#
|
||||
# Error: Invalid public key; the public key is empty or not present
|
||||
# HTTP Status code: 422
|
||||
# Error message: "invalid public key"
|
||||
# Exit code: 7
|
||||
#
|
||||
# Error: Expired token
|
||||
# HTTP Status code: 403
|
||||
# Error message: "token has expired"
|
||||
# Exit code: 8
|
||||
#
|
||||
# Error: Invalid claiming token; missing, undecryptable, invalid payload...
|
||||
# HTTP Status code: 422
|
||||
# Error message: "invalid token"
|
||||
# Exit code: 9
|
||||
#
|
||||
# Error: Duplicate agent id; an agent with the same id but a different public key is already registered in the cloud
|
||||
# HTTP Status code: 409
|
||||
# Error message: "duplicate agent id"
|
||||
# Exit code: 10
|
||||
#
|
||||
# Error: Already claimed in another workspace;
|
||||
# this agent (same id, same public key) already belongs to another workspace
|
||||
# HTTP Status code: 403
|
||||
# Error message: "claimed in another workspace"
|
||||
# Exit code: 11
|
||||
#
|
||||
# Error: Internal server error. Any other unexpected error (DB problems, etc.)
|
||||
# HTTP Status code: 500
|
||||
# Error message: "internal server error"
|
||||
# Exit code: 12
|
||||
|
||||
if command -v curl >/dev/null 2>&1 ; then
|
||||
URLTOOL="curl"
|
||||
elif command -v wget >/dev/null 2>&1 ; then
|
||||
URLTOOL="wget"
|
||||
else
|
||||
echo >&2 "I need curl or wget to proceed, but neither is available on this system."
|
||||
exit 3
|
||||
fi
|
||||
if ! command -v openssl >/dev/null 2>&1 ; then
|
||||
echo >&2 "I need openssl to proceed, but neither is available on this system."
|
||||
exit 3
|
||||
fi
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# defaults to allow running this script by hand
|
||||
|
||||
[ -z "${NETDATA_USER_CONFIG_DIR}" ] && NETDATA_USER_CONFIG_DIR="@configdir_POST@"
|
||||
MACHINE_GUID_FILE="@registrydir_POST@/netdata.public.unique.id"
|
||||
CLAIMING_DIR="${NETDATA_USER_CONFIG_DIR}/claim.d"
|
||||
TOKEN="unknown"
|
||||
URL_BASE="https://netdata.cloud"
|
||||
ID="unknown"
|
||||
ROOMS=""
|
||||
HOSTNAME=$(hostname)
|
||||
CLOUD_CERTIFICATE_FILE="${CLAIMING_DIR}/cloud_fullchain.pem"
|
||||
|
||||
# get the MACHINE_GUID by default
|
||||
if [ -r "${MACHINE_GUID_FILE}" ]; then
|
||||
ID="$(cat "${MACHINE_GUID_FILE}")"
|
||||
fi
|
||||
|
||||
# get token from file
|
||||
if [ -r "${CLAIMING_DIR}/token" ]; then
|
||||
TOKEN="$(cat "${CLAIMING_DIR}/token")"
|
||||
fi
|
||||
|
||||
# get rooms from file
|
||||
if [ -r "${CLAIMING_DIR}/rooms" ]; then
|
||||
ROOMS="$(cat "${CLAIMING_DIR}/rooms")"
|
||||
fi
|
||||
|
||||
for arg in "$@"
|
||||
do
|
||||
case $arg in
|
||||
-token=*) TOKEN=${arg:7} ;;
|
||||
-url=*) URL_BASE=${arg:5} ;;
|
||||
-id=*) ID=${arg:4} ;;
|
||||
-rooms=*) ROOMS=${arg:7} ;;
|
||||
-hostname=*) HOSTNAME=${arg:10} ;;
|
||||
*) echo >&2 "Unknown argument ${arg}"
|
||||
exit 1 ;;
|
||||
esac
|
||||
shift 1
|
||||
done
|
||||
|
||||
echo >&2 "Token: ****************"
|
||||
echo >&2 "Base URL: $URL_BASE"
|
||||
echo >&2 "Id: $ID"
|
||||
echo >&2 "Rooms: $ROOMS"
|
||||
echo >&2 "Hostname: $HOSTNAME"
|
||||
|
||||
# create the claiming directory for this user
|
||||
if [ ! -d "${CLAIMING_DIR}" ] ; then
|
||||
mkdir -p "${CLAIMING_DIR}" && chmod 0770 "${CLAIMING_DIR}"
|
||||
# shellcheck disable=SC2181
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo >&2 "Failed to create claiming working directory ${CLAIMING_DIR}"
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
if [ ! -w "${CLAIMING_DIR}" ] ; then
|
||||
echo >&2 "No write permission in claiming working directory ${CLAIMING_DIR}"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if [ ! -f "${CLAIMING_DIR}/private.pem" ] ; then
|
||||
echo >&2 "Generating private/public key for the first time."
|
||||
if ! openssl genrsa -out "${CLAIMING_DIR}/private.pem" 2048 ; then
|
||||
echo >&2 "Failed to generate private/public key pair."
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
if [ ! -f "${CLAIMING_DIR}/public.pem" ] ; then
|
||||
echo >&2 "Extracting public key from private key."
|
||||
if ! openssl rsa -in "${CLAIMING_DIR}/private.pem" -outform PEM -pubout -out "${CLAIMING_DIR}/public.pem" ; then
|
||||
echo >&2 "Failed to extract public key."
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
|
||||
TARGET_URL="${URL_BASE}/api/v1/workspaces/agents/${ID}"
|
||||
# shellcheck disable=SC2002
|
||||
KEY=$(cat "${CLAIMING_DIR}/public.pem" | tr '\n' '!' | sed -e 's/!/\\n/g')
|
||||
# shellcheck disable=SC2001
|
||||
[ -n "$ROOMS" ] && ROOMS=\"$(echo "$ROOMS" | sed s'/,/", "/g')\"
|
||||
|
||||
cat > "${CLAIMING_DIR}/tmpin.txt" <<EMBED_JSON
|
||||
{
|
||||
"agent": {
|
||||
"id": "$ID",
|
||||
"hostname": "$HOSTNAME"
|
||||
},
|
||||
"token": "$TOKEN",
|
||||
"rooms" : [ $ROOMS ],
|
||||
"publicKey" : "$KEY"
|
||||
}
|
||||
EMBED_JSON
|
||||
|
||||
|
||||
if [ "${URLTOOL}" = "curl" ] ; then
|
||||
URLCOMMAND="curl --connect-timeout 5 --retry 3 -s -i -X PUT -d \"@${CLAIMING_DIR}/tmpin.txt\""
|
||||
else
|
||||
URLCOMMAND="wget -T 15 -O - -q --save-headers --content-on-error=on --method=PUT \
|
||||
--body-file=\"${CLAIMING_DIR}/tmpin.txt\""
|
||||
fi
|
||||
|
||||
if [ -r "${CLOUD_CERTIFICATE_FILE}" ] ; then
|
||||
if [ "${URLTOOL}" = "curl" ] ; then
|
||||
URLCOMMAND="${URLCOMMAND} --cacert \"${CLOUD_CERTIFICATE_FILE}\""
|
||||
else
|
||||
URLCOMMAND="${URLCOMMAND} --ca-certificate \"${CLOUD_CERTIFICATE_FILE}\""
|
||||
fi
|
||||
fi
|
||||
|
||||
eval "${URLCOMMAND} \"${TARGET_URL}\"" | tee "${CLAIMING_DIR}/tmpout.txt"
|
||||
URLCOMMAND_EXIT_CODE=$?
|
||||
if [ "${URLTOOL}" = "wget" ] && [ "${URLCOMMAND_EXIT_CODE}" -eq 8 ] ; then
|
||||
# We consider the server issuing an error response a successful attempt at communicating
|
||||
URLCOMMAND_EXIT_CODE=0
|
||||
fi
|
||||
|
||||
rm -f "${CLAIMING_DIR}/tmpin.txt"
|
||||
|
||||
# Check if URLCOMMAND connected and received reply
|
||||
if [ "${URLCOMMAND_EXIT_CODE}" -ne 0 ] ; then
|
||||
echo >&2 "Failed to connect to ${URL_BASE}"
|
||||
rm -f "${CLAIMING_DIR}/tmpout.txt"
|
||||
exit 4
|
||||
fi
|
||||
|
||||
HTTP_STATUS_CODE=$(grep "HTTP" "${CLAIMING_DIR}/tmpout.txt" | awk -F " " '{print $2}')
|
||||
if [ "${HTTP_STATUS_CODE}" -ne 200 ] ; then
|
||||
ERROR_MESSAGE=$(grep "\"error\":" "${CLAIMING_DIR}/tmpout.txt" | awk -F "error\":\"" '{print $2}' | sed s'/"}//g')
|
||||
case ${ERROR_MESSAGE} in
|
||||
"invalid agent id") EXIT_CODE=6 ;;
|
||||
"invalid public key") EXIT_CODE=7 ;;
|
||||
"token has expired") EXIT_CODE=8 ;;
|
||||
"invalid token") EXIT_CODE=9 ;;
|
||||
"duplicate agent id") EXIT_CODE=10 ;;
|
||||
"claimed in another workspace") EXIT_CODE=11 ;;
|
||||
"internal server error") EXIT_CODE=12 ;;
|
||||
*) EXIT_CODE=5 ;;
|
||||
esac
|
||||
echo >&2 "Failed to claim agent."
|
||||
rm -f "${CLAIMING_DIR}/tmpout.txt"
|
||||
exit $EXIT_CODE
|
||||
fi
|
||||
|
||||
rm -f "${CLAIMING_DIR}/tmpout.txt"
|
||||
touch "${CLAIMING_DIR}/is_claimed"
|
||||
rm -f "${CLAIMING_DIR}/token"
|
||||
echo >&2 "Agent was successfully claimed."
|
|
@ -19,6 +19,8 @@ shutdown-agent
|
|||
Cleanup and exit the netdata agent.
|
||||
fatal-agent
|
||||
Log the state and halt the netdata agent.
|
||||
reload-claiming-state
|
||||
Reload agent claiming state from disk.
|
||||
```
|
||||
|
||||
Those commands are the same that can be sent to netdata via [signals](../daemon#command-line-options).
|
||||
|
|
|
@ -1282,6 +1282,7 @@ AC_CONFIG_FILES([
|
|||
web/gui/Makefile
|
||||
web/server/Makefile
|
||||
web/server/static/Makefile
|
||||
claim/Makefile
|
||||
])
|
||||
AC_OUTPUT
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ static cmd_status_t cmd_save_database_execute(char *args, char **message);
|
|||
static cmd_status_t cmd_reopen_logs_execute(char *args, char **message);
|
||||
static cmd_status_t cmd_exit_execute(char *args, char **message);
|
||||
static cmd_status_t cmd_fatal_execute(char *args, char **message);
|
||||
static cmd_status_t cmd_reload_claiming_state_execute(char *args, char **message);
|
||||
static cmd_status_t cmd_reload_labels_execute(char *args, char **message);
|
||||
|
||||
static command_info_t command_info_array[] = {
|
||||
|
@ -49,6 +50,7 @@ static command_info_t command_info_array[] = {
|
|||
{"reopen-logs", cmd_reopen_logs_execute, CMD_TYPE_ORTHOGONAL}, // Close and reopen log files
|
||||
{"shutdown-agent", cmd_exit_execute, CMD_TYPE_EXCLUSIVE}, // exit cleanly
|
||||
{"fatal-agent", cmd_fatal_execute, CMD_TYPE_HIGH_PRIORITY}, // exit with fatal error
|
||||
{"reload-claiming-state", cmd_reload_claiming_state_execute, CMD_TYPE_ORTHOGONAL}, // reload claiming state
|
||||
{"reload-labels", cmd_reload_labels_execute, CMD_TYPE_ORTHOGONAL}, // reload the labels
|
||||
};
|
||||
|
||||
|
@ -108,7 +110,9 @@ static cmd_status_t cmd_help_execute(char *args, char **message)
|
|||
"shutdown-agent\n"
|
||||
" Cleanup and exit the netdata agent.\n"
|
||||
"fatal-agent\n"
|
||||
" Log the state and halt the netdata agent.\n",
|
||||
" Log the state and halt the netdata agent.\n"
|
||||
"reload-claiming-state\n"
|
||||
" Reload agent claiming state from disk.\n",
|
||||
MAX_COMMAND_LENGTH - 1);
|
||||
return CMD_STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -176,6 +180,21 @@ static cmd_status_t cmd_fatal_execute(char *args, char **message)
|
|||
return CMD_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cmd_status_t cmd_reload_claiming_state_execute(char *args, char **message)
|
||||
{
|
||||
(void)args;
|
||||
(void)message;
|
||||
|
||||
info("The claiming feature is still in development and subject to change before the next release");
|
||||
return CMD_STATUS_FAILURE;
|
||||
|
||||
error_log_limit_unlimited();
|
||||
info("COMMAND: Reloading Agent Claiming configuration.");
|
||||
load_claiming_state();
|
||||
error_log_limit_reset();
|
||||
return CMD_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cmd_status_t cmd_reload_labels_execute(char *args, char **message)
|
||||
{
|
||||
(void)args;
|
||||
|
|
|
@ -19,6 +19,7 @@ typedef enum cmd {
|
|||
CMD_REOPEN_LOGS,
|
||||
CMD_EXIT,
|
||||
CMD_FATAL,
|
||||
CMD_RELOAD_CLAIMING_STATE,
|
||||
CMD_RELOAD_LABELS,
|
||||
CMD_TOTAL_COMMANDS
|
||||
} cmd_t;
|
||||
|
|
|
@ -60,6 +60,9 @@
|
|||
// netdata unit tests
|
||||
#include "unit_test.h"
|
||||
|
||||
// netdata agent claiming
|
||||
#include "claim/claim.h"
|
||||
|
||||
// the netdata deamon
|
||||
#include "daemon.h"
|
||||
#include "main.h"
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <sched.h>
|
||||
|
||||
char pidfile[FILENAME_MAX + 1] = "";
|
||||
char claimingdirectory[FILENAME_MAX + 1];
|
||||
|
||||
static void chown_open_file(int fd, uid_t uid, gid_t gid) {
|
||||
if(fd == -1) return;
|
||||
|
@ -50,6 +51,7 @@ int become_user(const char *username, int pid_fd) {
|
|||
|
||||
create_needed_dir(netdata_configured_cache_dir, uid, gid);
|
||||
create_needed_dir(netdata_configured_varlib_dir, uid, gid);
|
||||
create_needed_dir(claimingdirectory, uid, gid);
|
||||
|
||||
if(pidfile[0]) {
|
||||
if(chown(pidfile, uid, gid) == -1)
|
||||
|
@ -434,6 +436,9 @@ int become_daemon(int dont_fork, const char *user)
|
|||
// never become a problem
|
||||
sched_setscheduler_set();
|
||||
|
||||
// Set claiming directory based on user config directory with correct ownership
|
||||
snprintfz(claimingdirectory, FILENAME_MAX, "%s/claim.d", netdata_configured_user_config_dir);
|
||||
|
||||
if(user && *user) {
|
||||
if(become_user(user, pidfd) != 0) {
|
||||
error("Cannot become user '%s'. Continuing as we are.", user);
|
||||
|
@ -443,6 +448,7 @@ int become_daemon(int dont_fork, const char *user)
|
|||
else {
|
||||
create_needed_dir(netdata_configured_cache_dir, getuid(), getgid());
|
||||
create_needed_dir(netdata_configured_varlib_dir, getuid(), getgid());
|
||||
create_needed_dir(claimingdirectory, getuid(), getgid());
|
||||
}
|
||||
|
||||
if(pidfd != -1)
|
||||
|
|
|
@ -351,6 +351,8 @@ int help(int exitcode) {
|
|||
" set netdata.conf option from the command line.\n\n"
|
||||
" -W simple-pattern pattern string\n"
|
||||
" Check if string matches pattern and exit.\n\n"
|
||||
" -W \"claim -token=TOKEN -rooms=ROOM1,ROOM2\"\n"
|
||||
" Claim the agent to the workspace rooms pointed to by TOKEN and ROOM*.\n\n"
|
||||
);
|
||||
|
||||
fprintf(stream, "\n Signals netdata handles:\n\n"
|
||||
|
@ -926,6 +928,7 @@ int main(int argc, char **argv) {
|
|||
{
|
||||
char* stacksize_string = "stacksize=";
|
||||
char* debug_flags_string = "debug_flags=";
|
||||
char* claim_string = "claim";
|
||||
#ifdef ENABLE_DBENGINE
|
||||
char* createdataset_string = "createdataset=";
|
||||
char* stresstest_string = "stresstest=";
|
||||
|
@ -1086,6 +1089,10 @@ int main(int argc, char **argv) {
|
|||
printf("%s\n", value);
|
||||
return 0;
|
||||
}
|
||||
else if(strncmp(optarg, claim_string, strlen(claim_string)) == 0) {
|
||||
/* will trigger a claiming attempt when the agent is initialized */
|
||||
claiming_pending_arguments = optarg + strlen(claim_string);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Unknown -W parameter '%s'\n", optarg);
|
||||
return help(1);
|
||||
|
@ -1271,6 +1278,14 @@ int main(int argc, char **argv) {
|
|||
get_system_info(system_info);
|
||||
|
||||
rrd_init(netdata_configured_hostname, system_info);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Claim netdata agent to a cloud endpoint
|
||||
|
||||
if (claiming_pending_arguments)
|
||||
claim_agent(claiming_pending_arguments);
|
||||
load_claiming_state();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// enable log flood protection
|
||||
|
||||
|
|
|
@ -617,6 +617,7 @@ NETDATA_LOG_DIR="$(config_option "global" "log directory" "${NETDATA_PREFIX}/var
|
|||
NETDATA_USER_CONFIG_DIR="$(config_option "global" "config directory" "${NETDATA_PREFIX}/etc/netdata")"
|
||||
NETDATA_STOCK_CONFIG_DIR="$(config_option "global" "stock config directory" "${NETDATA_PREFIX}/usr/lib/netdata/conf.d")"
|
||||
NETDATA_RUN_DIR="${NETDATA_PREFIX}/var/run"
|
||||
NETDATA_CLAIMING_DIR="${NETDATA_USER_CONFIG_DIR}/claim.d"
|
||||
|
||||
cat <<OPTIONSEOF
|
||||
|
||||
|
@ -690,6 +691,15 @@ done
|
|||
|
||||
run chmod 755 "${NETDATA_LOG_DIR}"
|
||||
|
||||
# --- claiming dir ----
|
||||
|
||||
if [ ! -d "${NETDATA_CLAIMING_DIR}" ]; then
|
||||
echo >&2 "Creating directory '${NETDATA_CLAIMING_DIR}'"
|
||||
run mkdir -p "${NETDATA_CLAIMING_DIR}" || exit 1
|
||||
fi
|
||||
run chown -R "${NETDATA_USER}:${NETDATA_GROUP}" "${NETDATA_CLAIMING_DIR}"
|
||||
run chmod 770 "${NETDATA_CLAIMING_DIR}"
|
||||
|
||||
# --- plugins ----
|
||||
|
||||
if [ "${UID}" -eq 0 ]; then
|
||||
|
|
|
@ -313,6 +313,7 @@ if [ -n "${NETDATA_PREFIX}" ] && [ -d "${NETDATA_PREFIX}" ]; then
|
|||
else
|
||||
rm_file "/usr/sbin/netdata"
|
||||
rm_file "/usr/sbin/netdatacli"
|
||||
rm_file "/usr/sbin/netdata-claim.sh"
|
||||
rm_dir "/usr/share/netdata"
|
||||
rm_dir "/usr/libexec/netdata"
|
||||
rm_dir "/var/lib/netdata"
|
||||
|
|
Loading…
Reference in New Issue