summaryrefslogtreecommitdiffstats
path: root/src/file/format/mod.rs
blob: 39b38135460aa3a2e6ae6aea3852c757aaf3bf90 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// If no features are used, there is an "unused mut" warning in `ALL_EXTENSIONS`
// BUG: ? For some reason this doesn't do anything if I try and function scope this
#![allow(unused_mut)]

use source::Source;
use std::collections::HashMap;
use std::error::Error;
use value::Value;

#[cfg(feature = "toml")]
mod toml;

#[cfg(feature = "json")]
mod json;

#[cfg(feature = "yaml")]
mod yaml;

#[cfg(feature = "hjson")]
mod hjson;

#[cfg(feature = "ini")]
mod ini;

#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum FileFormat {
    /// TOML (parsed with toml)
    #[cfg(feature = "toml")]
    Toml,

    /// JSON (parsed with serde_json)
    #[cfg(feature = "json")]
    Json,

    /// YAML (parsed with yaml_rust)
    #[cfg(feature = "yaml")]
    Yaml,

    /// HJSON (parsed with serde_hjson)
    #[cfg(feature = "hjson")]
    Hjson,
    /// INI (parsed with rust_ini)
    #[cfg(feature = "ini")]
    Ini,
}

lazy_static! {
    #[doc(hidden)]
    // #[allow(unused_mut)] ?
    pub static ref ALL_EXTENSIONS: HashMap<FileFormat, Vec<&'static str>> = {
        let mut formats: HashMap<FileFormat, Vec<_>> = HashMap::new();

        #[cfg(feature = "toml")]
        formats.insert(FileFormat::Toml, vec!["toml"]);

        #[cfg(feature = "json")]
        formats.insert(FileFormat::Json, vec!["json"]);

        #[cfg(feature = "yaml")]
        formats.insert(FileFormat::Yaml, vec!["yaml", "yml"]);

        #[cfg(feature = "hjson")]
        formats.insert(FileFormat::Hjson, vec!["hjson"]);

        #[cfg(feature = "ini")]
        formats.insert(FileFormat::Ini, vec!["ini"]);

        formats
    };
}

impl FileFormat {
    // TODO: pub(crate)
    #[doc(hidden)]
    pub fn extensions(&self) -> &'static Vec<&'static str> {
        // It should not be possible for this to fail
        // A FileFormat would need to be declared without being added to the
        // ALL_EXTENSIONS map.
        ALL_EXTENSIONS.get(self).unwrap()
    }

    // TODO: pub(crate)
    #[doc(hidden)]
    #[allow(unused_variables)]
    pub fn parse(
        &self,
        uri: Option<&String>,
        text: &str,
    ) -> Result<HashMap<String, Value>, Box<Error + Send + Sync>> {
        match *self {
            #[cfg(feature = "toml")]
            FileFormat::Toml => toml::parse(uri, text),

            #[cfg(feature = "json")]
            FileFormat::Json => json::parse(uri, text),

            #[cfg(feature = "yaml")]
            FileFormat::Yaml => yaml::parse(uri, text),

            #[cfg(feature = "hjson")]
            FileFormat::Hjson => hjson::parse(uri, text),

            #[cfg(feature = "ini")]
            FileFormat::Ini => ini::parse(uri, text),
        }
    }
}
or: Invalid public key; the public key is empty or not present # HTTP Status code: 422 # Exit code: 11 ERROR_KEYS[11]="ErrInvalidPublicKey" ERROR_MESSAGES[11]="invalid public key" # # Error: Expired, missing or invalid token # HTTP Status code: 403 # Exit code: 12 ERROR_KEYS[12]="ErrForbidden" ERROR_MESSAGES[12]="token expired/token not found/invalid token" # Error: Duplicate agent id; an agent with the same id is already registered in the cloud # HTTP Status code: 409 # Exit code: 13 ERROR_KEYS[13]="ErrAlreadyClaimed" ERROR_MESSAGES[13]="already claimed" # Error: The node claiming process is still in progress. # HTTP Status code: 102 # Exit code: 14 ERROR_KEYS[14]="ErrProcessingClaim" ERROR_MESSAGES[14]="processing claiming" # Error: Internal server error. Any other unexpected error (DB problems, etc.) # HTTP Status code: 500 # Exit code: 15 ERROR_KEYS[15]="ErrInternalServerError" ERROR_MESSAGES[15]="Internal Server Error" # Error: There was a timout processing the claim. # HTTP Status code: 504 # Exit code: 16 ERROR_KEYS[16]="ErrGatewayTimeout" ERROR_MESSAGES[16]="Gateway Timeout" # Error: The service cannot handle the claiming request at this time. # HTTP Status code: 503 # Exit code: 17 ERROR_KEYS[17]="ErrServiceUnavailable" ERROR_MESSAGES[17]="Service Unavailable" get_config_value() { conf_file="${1}" section="${2}" key_name="${3}" config_result=$(@sbindir_POST@/netdatacli 2>/dev/null read-config "$conf_file|$section|$key_name"; exit $?) # shellcheck disable=SC2181 if [ "$?" != "0" ]; then echo >&2 "cli failed, assume netdata is not running and query the on-disk config" config_result=$(@sbindir_POST@/netdata 2>/dev/null -W get2 "$conf_file" "$section" "$key_name" unknown_default) fi echo "$config_result" } 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 it is not available on this system." exit 3 fi # shellcheck disable=SC2050 if [ "@enable_cloud_POST@" = "no" ]; then echo >&2 "This agent was built with --disable-cloud and cannot be claimed" exit 3 fi # shellcheck disable=SC2050 if [ "@can_enable_aclk_POST@" != "yes" ]; then echo >&2 "This agent was built without the dependencies for Cloud and cannot be claimed" exit 3 fi # ----------------------------------------------------------------------------- # defaults to allow running this script by hand [ -z "${NETDATA_VARLIB_DIR}" ] && NETDATA_VARLIB_DIR="@varlibdir_POST@" MACHINE_GUID_FILE="@registrydir_POST@/netdata.public.unique.id" CLAIMING_DIR="${NETDATA_VARLIB_DIR}/cloud.d" TOKEN="unknown" URL_BASE=$(get_config_value cloud global "cloud base url") [ -z "$URL_BASE" ] && URL_BASE="https://app.netdata.cloud" # Cover post-install with --dont-start ID="unknown" ROOMS="" [ -z "$HOSTNAME" ] && HOSTNAME=$(hostname) CLOUD_CERTIFICATE_FILE="${CLAIMING_DIR}/cloud_fullchain.pem" VERBOSE=0 INSECURE=0 RELOAD=1 NETDATA_USER=$(get_config_value netdata global "run as user") [ -z "$EUID" ] && EUID="$(id -u)" # 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} ;; -verbose) VERBOSE=1 ;; -insecure) INSECURE=1 ;; -proxy=*) PROXY=${arg:7} ;; -noproxy) NOPROXY=yes ;; -noreload) RELOAD=0 ;; -user=*) NETDATA_USER=${arg:6} ;; *) echo >&2 "Unknown argument ${arg}" exit 1 ;; esac shift 1 done if [ "$EUID" != "0" ] && [ "$(whoami)" != "$NETDATA_USER" ]; then echo >&2 "This script must be run by the $NETDATA_USER user account" exit 6 fi # if curl not installed give warning SOCKS can't be used if [[ "${URLTOOL}" != "curl" && "${PROXY:0:5}" = socks ]] ; then echo >&2 "wget doesn't support SOCKS. Please install curl or disable SOCKS proxy." exit 1 fi echo >&2 "Token: ****************" echo >&2 "Base URL: $URL_BASE" echo >&2 "Id: $ID" echo >&2 "Rooms: $ROOMS" echo >&2 "Hostname: $HOSTNAME" echo >&2 "Proxy: $PROXY" echo >&2 "Netdata user: $NETDATA_USER" # 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/spaces/nodes/${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 { "node": { "id": "$ID", "hostname": "$HOSTNAME" }, "token": "$TOKEN", "rooms" : [ $ROOMS ], "publicKey" : "$KEY" } EMBED_JSON if [ "${VERBOSE}" == 1 ] ; then echo "Request to server:" cat "${CLAIMING_DIR}/tmpin.txt" fi if [ "${URLTOOL}" = "curl" ] ; then URLCOMMAND="curl --connect-timeout 5 --retry 0 -s -i -X PUT -d \"@${CLAIMING_DIR}/tmpin.txt\"" if [ "${NOPROXY}" = "yes" ] ; then URLCOMMAND="${URLCOMMAND} -x \"\"" elif [ -n "${PROXY}" ] ; then URLCOMMAND="${URLCOMMAND} -x \"${PROXY}\"" fi else URLCOMMAND="wget -T 15 -O - -q --save-headers --content-on-error=on --method=PUT \ --body-file=\"${CLAIMING_DIR}/tmpin.txt\"" if [ "${NOPROXY}" = "yes" ] ; then URLCOMMAND="${URLCOMMAND} --no-proxy"