/** The watcher-set command */ int cmd_watcher_set (int argc, const char *argv[]) { if (OPTIONS.tenant[0] == 0) { fprintf (stderr, "%% No tenantid provided\n"); return 1; } if (OPTIONS.meter[0] == 0) { fprintf (stderr, "%% No meter provided\n"); return 1; } if (OPTIONS.match[0] == 0) { fprintf (stderr, "%% No match provided\n"); return 1; } if (OPTIONS.value[0] == 0) { fprintf (stderr, "%% No value provided\n"); return 1; } var *mdef = api_get ("/%s/meter", OPTIONS.tenant); if (! mdef) return 1; var *mdef_m = var_get_dict_forkey (mdef, "meter"); var *mde_meter = var_get_dict_forkey (mdef_m, OPTIONS.meter); const char *inftype = var_get_str_forkey (mde_meter, "type"); var *req = var_alloc(); var *req_watcher = var_get_dict_forkey (req, "watcher"); var *reql = var_get_dict_forkey (req_watcher, OPTIONS.level); if (OPTIONS.host[0] == 0) { var_set_str_forkey (reql, "cmp", OPTIONS.match); } if (strcmp (inftype, "integer") == 0) { var_set_int_forkey (reql, "val", strtoull (OPTIONS.value, NULL, 10)); } else if (strcmp (inftype, "frac") == 0) { var_set_double_forkey (reql, "val", atof (OPTIONS.value)); } else { var_set_str_forkey (reql, "val", OPTIONS.value); } var_set_double_forkey (reql, "weight", atof (OPTIONS.weight)); var *apires; if (OPTIONS.host[0]) { apires = api_call ("POST", req, "/%s/host/%s/watcher/%s", OPTIONS.tenant, OPTIONS.host, OPTIONS.meter); } else { apires = api_call ("POST", req, "/%s/watcher/%s", OPTIONS.tenant, OPTIONS.meter); } var_free (mdef); var_free (req); var_free (apires); return 0; }
/** The meter-create command */ int cmd_meter_create (int argc, const char *argv[]) { if (OPTIONS.tenant[0] == 0) { fprintf (stderr, "%% No tenantid provided\n"); return 1; } if (OPTIONS.meter[0] == 0) { fprintf (stderr, "%% No meter provided\n"); return 1; } var *req = var_alloc(); var *req_meter = var_get_dict_forkey (req, "meter"); var_set_str_forkey (req_meter, "type", OPTIONS.type); if (OPTIONS.description[0]) { var_set_str_forkey (req_meter, "description", OPTIONS.description); } if (OPTIONS.unit[0]) { var_set_str_forkey (req_meter, "unit", OPTIONS.unit); } var *apires = api_call ("POST",req,"/%s/meter/%s", OPTIONS.tenant, OPTIONS.meter); var_free (req); var_free (apires); return 0; }
/** The tenant-create command */ int cmd_tenant_create (int argc, const char *argv[]) { uuid tenant; /* Avoid using the default tenant in this case */ disregard_default_tenant(); if (OPTIONS.tenant[0] == 0) { tenant = uuidgen(); OPTIONS.tenant = (const char *) malloc (40); uuid2str (tenant, (char *) OPTIONS.tenant); } else { tenant = mkuuid (OPTIONS.tenant); } var *req = var_alloc(); var *req_tenant = var_get_dict_forkey (req, "tenant"); if (OPTIONS.key[0]) { var_set_str_forkey (req_tenant, "key", OPTIONS.key); } if (OPTIONS.name[0]) { var_set_str_forkey (req_tenant, "name", OPTIONS.name); } var *apires = api_call ("POST", req, "/%s", OPTIONS.tenant); if (apires) { var *r = var_get_dict_forkey (apires, "tenant"); printf ("Tenant created:\n" "---------------------------------------------" "-----------------------------------\n" " Name: %s\n" " UUID: %s\n" " AES Key: %s\n" "---------------------------------------------" "-----------------------------------\n", var_get_str_forkey (r, "name"), OPTIONS.tenant, var_get_str_forkey (r, "key")); } var_free (req); var_free (apires); return 0; }
var *tenant_overview (tenant *t) { var *res = var_alloc(); var *ov = var_get_dict_forkey (res, "overview"); host *h = t->first; while (h) { host_to_overview (h, ov); h = h->next; } return res; }
/** The watcher-list command */ int cmd_watcher_list (int argc, const char *argv[]) { if (OPTIONS.tenant[0] == 0) { fprintf (stderr, "%% No tenantid provided\n"); return 1; } var *apires; if (OPTIONS.host[0]) { apires = api_get ("/%s/host/%s/watcher", OPTIONS.tenant, OPTIONS.host); } else { apires = api_get ("/%s/watcher", OPTIONS.tenant); } if (OPTIONS.json) { var_dump (apires, stdout); var_free (apires); return 0; } printf ("From Meter Trigger Match " "Value Weight\n" "-------------------------------------------------------" "-------------------------\n"); var *apiwatch = var_get_dict_forkey (apires, "watcher"); if (var_get_count (apiwatch)) { var *crsr = apiwatch->value.arr.first; while (crsr) { print_data (crsr->id, "warning", var_get_dict_forkey (crsr, "warning")); print_data (crsr->id, "alert", var_get_dict_forkey (crsr, "alert")); print_data (crsr->id, "critical", var_get_dict_forkey (crsr, "critical")); crsr = crsr->next; } printf ("---------------------------------------------" "-----------------------------------\n"); } var_free (apires); return 0; }
int cmd_host_overview (int argc, const char *argv[]) { if (OPTIONS.tenant[0] == 0) { fprintf (stderr, "%% No tenantid provided\n"); return 1; } var *ov = api_get ("/%s/host/overview", OPTIONS.tenant); if (! var_get_count (ov)) return 0; printf ("Name Status " "Load Net i/o CPU\n"); printf ("---------------------------------------------" "-----------------------------------\n"); var *ov_dict = var_get_dict_forkey (ov, "overview"); if (! var_get_count (ov_dict)) return 0; var *crsr = ov_dict->value.arr.first; while (crsr) { const char *hname = var_get_str_forkey (crsr, "hostname"); if (! hname) hname = ""; char shortname[32]; strncpy (shortname, hname, 31); shortname[31] = 0; const char *hstat = var_get_str_forkey (crsr, "status"); if (! hstat ) hstat = "UNSET"; double load = var_get_double_forkey (crsr, "loadavg"); uint64_t netio = var_get_int_forkey (crsr, "net/in_kbs"); netio += var_get_int_forkey (crsr, "net/out_kbs"); double cpu = var_get_double_forkey (crsr, "pcpu"); int rcpu = (cpu+5.0) / 10; printf ("%-31s %-8s %6.2f %8llu %6.2f %% -[", shortname, hstat, load, netio, cpu); for (int i=0; i<10; i++) { if (i< rcpu) printf ("#"); else printf (" "); } printf ("]+\n"); crsr = crsr->next; } var_free (ov); printf ("---------------------------------------------" "-----------------------------------\n"); return 0; }
void host_to_overview (host *h, var *ovdict) { char mid[16]; char uuidstr[40]; uuid2str (h->uuid, uuidstr); var *res = var_get_dict_forkey (ovdict, uuidstr); meter *m = h->first; while (m) { if (m->count >= SZ_EMPTY_VAL) { m = m->next; continue; } id2str (m->id, mid); if ((strncmp (mid, "top/", 4) == 0) || (strncmp (mid, "df/", 3) == 0) || (strncmp (mid, "proc/", 5) == 0) || (strncmp (mid, "os/", 3) == 0) || (strncmp (mid, "who/", 4) == 0)) { m = m->next; continue; } switch (m->id & MMASK_TYPE) { case MTYPE_INT: var_set_int_forkey (res, mid, meter_get_uint (m, 0)); break; case MTYPE_FRAC: var_set_double_forkey (res, mid, meter_get_frac (m, 0)); break; case MTYPE_STR: var_set_str_forkey (res, mid, m->d.str[0].str); break; default: break; } m = m->next; } }
/** The meter-list command */ int cmd_meter_list (int argc, const char *argv[]) { if (OPTIONS.tenant[0] == 0) { fprintf (stderr, "%% No tenantid provided\n"); return 1; } var *apires = api_get ("/%s/meter", OPTIONS.tenant); if (OPTIONS.json) { var_dump (apires, stdout); } else { var *res_meter = var_get_dict_forkey (apires, "meter"); if (var_get_count (res_meter)) { printf ("From Meter Type Unit Description\n"); printf ("----------------------------------------" "----------------------------------------\n"); var *crsr = res_meter->value.arr.first; while (crsr) { const char *desc = var_get_str_forkey (crsr, "description"); const char *type = var_get_str_forkey (crsr, "type"); const char *unit = var_get_str_forkey (crsr, "unit"); const char *org = var_get_str_forkey (crsr, "origin"); if (!desc) desc = "-"; if (!unit) unit = ""; if (!org) org = "default"; printf ("%-8s %-12s %-8s %-7s %s\n", org, crsr->id, type, unit, desc); crsr = crsr->next; } printf ("---------------------------------------------" "-----------------------------------\n"); } } var_free (apires); return 0; }
/** The tenant-set-metadata command */ int cmd_tenant_set_metadata (int argc, const char *argv[]) { if (argc < 4) { fprintf (stderr, "%% Missing key and value arguments\n"); return 1; } const char *key = argv[2]; const char *val = argv[3]; if (OPTIONS.tenant[0] == 0) { fprintf (stderr, "%% No tenantid provided\n"); return 1; } var *api_meta = api_get ("/%s/meta", OPTIONS.tenant); var *meta = var_get_dict_forkey (api_meta, "metadata"); var_set_str_forkey (meta, key, val); var *res = api_call ("POST", api_meta, "/%s/meta", OPTIONS.tenant); var_free (api_meta); var_free (res); return 0; }
int main (int argc, const char *argv[]) { const char *tstr = NULL; var *env = var_alloc(); var *env_collector = var_get_dict_forkey (env, "collector"); var *env_colors = var_get_array_forkey (env, "colors"); var_set_int_forkey (env_collector, "listenport", 3333); var_set_str_forkey (env_collector, "address", "127.0.0.1"); var_set_str_forkey (env_collector, "key", "secret"); var_clear_array (env_colors); var_add_str (env_colors, "red"); var_add_str (env_colors, "green"); var_add_str (env_colors, "blue"); assert (var_get_int_forkey (env_collector, "listenport") == 3333); assert (tstr = var_get_str_forkey (env_collector, "address")); assert (strcmp (tstr, "127.0.0.1") == 0); assert (tstr = var_get_str_forkey (env_collector, "key")); assert (strcmp (tstr, "secret") == 0); assert (var_get_count (env_collector) == 3); assert (tstr = var_get_str_atindex (env_colors, 0)); assert (strcmp (tstr, "red") == 0); assert (tstr = var_get_str_atindex (env_colors, 1)); assert (strcmp (tstr, "green") == 0); assert (tstr = var_get_str_atindex (env_colors, 2)); assert (strcmp (tstr, "blue") == 0); time_t tnow = time (NULL); var_set_time_forkey (env, "nowtime", tnow); assert (var_get_time_forkey (env, "nowtime") == tnow); var_set_unixtime_forkey (env, "unixtime", tnow); assert (var_get_time_forkey (env, "unixtime") == tnow); uuid uuid_in = uuidgen(); var_set_uuid_forkey (env, "myuuid", uuid_in); uuid uuid_out = var_get_uuid_forkey (env, "myuuid"); assert (uuidcmp (uuid_in, uuid_out)); var_new_generation (env); var_set_int_forkey (env_collector, "listenport", 3333); var_set_str_forkey (env_collector, "address", "192.168.1.1"); var_clear_array (env_colors); var_add_str (env_colors, "red"); var_add_str (env_colors, "green"); var_add_str (env_colors, "blue"); var *lport, *addr, *key; lport = var_find_key (env_collector, "listenport"); addr = var_find_key (env_collector, "address"); key = var_find_key (env_collector, "key"); assert (lport); assert (addr); assert (key); /* collector.listenport should be unchanged from first generation */ assert (lport->generation == env->generation); assert (lport->lastmodified < env->generation); assert (lport->firstseen == lport->lastmodified); /* collector.addr should be changed this generation */ assert (addr->generation == env->generation); assert (addr->lastmodified == env->generation); assert (addr->firstseen == env->firstseen); /* colors should be changed this generation */ assert (env_colors->generation == env->generation); assert (env_colors->lastmodified == env->generation); assert (env_colors->firstseen == env->firstseen); /* collector.key should be stale */ assert (key->generation < env->generation); var_clean_generation (env); /* collector.key should now be deleted */ key = var_find_key (env_collector, "key"); assert (key == NULL); return 0; }
/** Internal state machine for parsing a JSON-like configuration * text. Recurses on itself for new levels of hierarchy. * \param v The var at this cursor level. * \param buf The cursor (inout) * \param st The state to start out with. */ static int var_parse_json_level (var *v, const char **buf, parse_state st, int depth) { if (depth > default_max_json_depth) { sprintf (LAST_PARSE_ERROR, "Nested to deep"); return 0; } const char *c = *buf; var *vv = NULL; char keybuf[4096]; int keybuf_pos = 0; char valuebuf[4096]; int valuebuf_pos = 0; int value_nondigits = 0; int value_dots = 0; parse_state stnext; while (*c) { switch (st) { case PSTATE_BEGINNING: if (*c == '{') { st = PSTATE_DICT_WAITKEY; break; } /* intentional fall-through */ case PSTATE_DICT_WAITKEY: if (*c == '#') { stnext = st; st = PSTATE_COMMENT; break; } if (isspace (*c)) break; if (*c == ',') break; if (*c == '}') { *buf = c; return 1; } if (*c == '\"') st = PSTATE_DICT_KEY_QUOTED; else { if (! strchr (VALIDUNQUOTED, *c)) { sprintf (LAST_PARSE_ERROR, "Invalid char for " "key: '%c'", *c); return 0; } --c; st = PSTATE_DICT_KEY; } keybuf_pos = 0; keybuf[0] = 0; valuebuf_pos = 0; valuebuf[0] = 0; break; case PSTATE_DICT_KEY: if (*c == '#') { stnext = PSTATE_DICT_WAITVALUE; st = PSTATE_COMMENT; break; } if (isspace (*c)) { st = PSTATE_DICT_WAITVALUE; break; } if (*c == '{') { *buf = c+1; vv = var_get_dict_forkey (v, keybuf); if (! vv) { sprintf (LAST_PARSE_ERROR, "Couldn't get dict " "for key '%s'", keybuf); return 0; } if (!var_parse_json_level (vv, buf, PSTATE_DICT_WAITKEY, depth+1)) { return 0; } c = *buf; st = PSTATE_DICT_WAITKEY; break; } if (*c == '[') { *buf = c+1; vv = var_get_array_forkey (v, keybuf); if (! vv) { sprintf (LAST_PARSE_ERROR, "Couldn't get array " "for key '%s'", keybuf); return 0; } var_clear_array (vv); if (!var_parse_json_level (vv, buf, PSTATE_ARRAY_WAITVALUE, depth+1)) { return 0; } c = *buf; st = PSTATE_DICT_WAITKEY; break; } if (*c == ':') { st = PSTATE_DICT_WAITVALUE; break; } if (! strchr (VALIDUNQUOTED, *c)) { sprintf (LAST_PARSE_ERROR, "Invalid character in " "value '%c'", *c); return 0; } if (keybuf_pos >= 4095) return 0; keybuf[keybuf_pos++] = *c; keybuf[keybuf_pos] = 0; break; case PSTATE_DICT_KEY_QUOTED: if (*c == '\"') { st = PSTATE_DICT_WAITVALUE; break; } if (*c == '\\') ++c; if (keybuf_pos >= 4095) return 0; keybuf[keybuf_pos++] = *c; keybuf[keybuf_pos] = 0; break; case PSTATE_DICT_WAITVALUE: if (*c == '#') { stnext = st; st = PSTATE_COMMENT; break; } if (isspace (*c)) break; if (*c == ':') break; if (*c == '=') break; if (*c == '{') { *buf = c+1; vv = var_get_dict_forkey (v, keybuf); if (! vv) { sprintf (LAST_PARSE_ERROR, "Couldn't get dict for " "key '%s'", keybuf); return 0; } if (!var_parse_json_level (vv, buf, PSTATE_DICT_WAITKEY, depth+1)) { return 0; } c = *buf; st = PSTATE_DICT_WAITKEY; break; } if (*c == '[') { *buf = c+1; vv = var_get_array_forkey (v, keybuf); if (! vv) { sprintf (LAST_PARSE_ERROR, "Couldn't get array " "for key '%s'", keybuf); return 0; } var_clear_array (vv); if (!var_parse_json_level (vv, buf, PSTATE_ARRAY_WAITVALUE, depth+1)) { return 0; } c = *buf; st = PSTATE_DICT_WAITKEY; break; } if (*c == '\"') { st = PSTATE_DICT_VALUE_QUOTED; } else { if (! strchr (VALIDUNQUOTEDV, *c)) { sprintf (LAST_PARSE_ERROR, "Invalid character for " "value: '%c'", *c); return 0; } --c; value_nondigits = 0; value_dots = 0; st = PSTATE_DICT_VALUE; } valuebuf_pos = 0; valuebuf[0] = 0; break; case PSTATE_DICT_VALUE: if (isspace (*c) || (*c == ',') || (*c == '}') || (*c == '#')) { if ((! value_nondigits) && (value_dots < 2)) { if (value_dots == 0) { var_set_int_forkey (v, keybuf, strtoull(valuebuf, NULL, 10)); } else { var_set_double_forkey (v, keybuf, atof(valuebuf)); } } else var_set_str_forkey (v, keybuf, valuebuf); if (*c == '#') { stnext = PSTATE_DICT_WAITKEY; st = PSTATE_COMMENT; break; } if (*c == '}') { *buf = c; return 1; } st = PSTATE_DICT_WAITKEY; break; } if (! strchr (VALIDUNQUOTEDV, *c)) { sprintf (LAST_PARSE_ERROR, "Invalid character in " "value for '%s': '%c'", keybuf, *c); return 0; } if (*c == '.') value_dots++; else if ((!value_nondigits) && (*c<'0' || *c>'9')) { value_nondigits = 1; } if (valuebuf_pos >= 4095) return 0; valuebuf[valuebuf_pos++] = *c; valuebuf[valuebuf_pos] = 0; break; case PSTATE_DICT_VALUE_QUOTED: if (*c == '\"') { var_set_str_forkey (v, keybuf, valuebuf); st = PSTATE_DICT_WAITKEY; break; } if (*c == '\\') ++c; if (valuebuf_pos >= 4095) return 0; valuebuf[valuebuf_pos++] = *c; valuebuf[valuebuf_pos] = 0; break; case PSTATE_ARRAY_WAITVALUE: if (*c == '#') { stnext = st; st = PSTATE_COMMENT; break; } if (isspace (*c)) break; if (*c == ',') break; if (*c == ']') { *buf = c; return 1; } if (*c == '{') { *buf = c+1; vv = var_add_dict (v); if (! vv) { sprintf (LAST_PARSE_ERROR, "Couldn't add dict"); return 0; } if (!var_parse_json_level (vv, buf, PSTATE_DICT_WAITKEY, depth+1)) { return 0; } c = *buf; st = PSTATE_ARRAY_WAITVALUE; break; } if (*c == '[') { *buf = c+1; vv = var_add_array (v); if (! vv) { sprintf (LAST_PARSE_ERROR, "Couldn't add array"); return 0; } var_clear_array (vv); if (!var_parse_json_level (vv, buf, PSTATE_ARRAY_WAITVALUE, depth+1)) { return 0; } c = *buf; st = PSTATE_ARRAY_WAITVALUE; break; } if (*c == '\"') { st = PSTATE_ARRAY_VALUE_QUOTED; } else { if (! strchr (VALIDUNQUOTED, *c)) return 0; --c; value_nondigits = 0; value_dots = 0; st = PSTATE_ARRAY_VALUE; } valuebuf_pos = 0; valuebuf[0] = 0; break; case PSTATE_ARRAY_VALUE: if (isspace (*c) || (*c == ']') || (*c == ',') || (*c == '#')) { if ((! value_nondigits) && (value_dots<2)) { if (value_dots == 0) { var_add_int (v, strtoull (valuebuf, NULL, 10)); } else { var_add_double (v, atof (valuebuf)); } } else var_add_str (v, valuebuf); if (*c == '#') { stnext = PSTATE_ARRAY_WAITVALUE; st = PSTATE_COMMENT; break; } if (*c == ']') { *buf = c; return 1; } st = PSTATE_ARRAY_WAITVALUE; break; } if (! strchr (VALIDUNQUOTEDV, *c)) return 0; if (*c == '.') value_dots++; else if ((!value_nondigits) && (*c<'0' || *c>'9')) { value_nondigits = 1; } if (valuebuf_pos >= 4095) return 0; valuebuf[valuebuf_pos++] = *c; valuebuf[valuebuf_pos] = 0; break; case PSTATE_ARRAY_VALUE_QUOTED: if (*c == '\"') { var_add_str (v, valuebuf); st = PSTATE_ARRAY_WAITVALUE; break; } if (*c == '\\') ++c; if (valuebuf_pos >= 4095) return 0; valuebuf[valuebuf_pos++] = *c; valuebuf[valuebuf_pos] = 0; break; case PSTATE_COMMENT: if (*c == '\n') { st = stnext; } break; } ++c; *buf = c; } return 1; }
/** If OPTIONS.tenant is the default, unset it */ void disregard_default_tenant (void) { var *conf_defaults = var_get_dict_forkey (OPTIONS.conf, "defaults"); const char *deftenant = var_get_str_forkey (conf_defaults, "tenant"); if (! deftenant) return; if (strcmp (deftenant, OPTIONS.tenant) == 0) OPTIONS.tenant = ""; }