Add new bond control commands to CLI

This commit is contained in:
Joseph Henry 2020-11-23 09:59:28 -08:00
parent 8af4eff43e
commit ecfac0601a
7 changed files with 395 additions and 42 deletions

198
one.cpp
View file

@ -491,6 +491,198 @@ static int cli(int argc,char **argv)
printf("%u %s %s" ZT_EOL_S,scode,command.c_str(),responseBody.c_str());
return 1;
}
} else if (command == "bond") {
/* zerotier-cli bond */
if (arg1.empty()) {
printf("(bond) command is missing required arugments" ZT_EOL_S);
return 2;
}
/* zerotier-cli bond list */
if (arg1 == "list") {
fprintf(stderr, "zerotier-cli bond list\n");
const unsigned int scode = Http::GET(1024 * 1024 * 16,60000,(const struct sockaddr *)&addr,"/bonds",requestHeaders,responseHeaders,responseBody);
if (scode == 0) {
printf("Error connecting to the ZeroTier service: %s\n\nPlease check that the service is running and that TCP port 9993 can be contacted via 127.0.0.1." ZT_EOL_S, responseBody.c_str());
return 1;
}
nlohmann::json j;
try {
j = OSUtils::jsonParse(responseBody);
} catch (std::exception &exc) {
printf("%u %s invalid JSON response (%s)" ZT_EOL_S,scode,command.c_str(),exc.what());
return 1;
} catch ( ... ) {
printf("%u %s invalid JSON response (unknown exception)" ZT_EOL_S,scode,command.c_str());
return 1;
}
if (scode == 200) {
if (json) {
printf("%s" ZT_EOL_S,OSUtils::jsonDump(j).c_str());
} else {
bool bFoundBond = false;
printf(" <peer> <bondtype> <status> <links>" ZT_EOL_S);
if (j.is_array()) {
for(unsigned long k=0;k<j.size();++k) {
nlohmann::json &p = j[k];
bool isBonded = p["isBonded"];
int8_t bondingPolicy = p["bondingPolicy"];
bool isHealthy = p["isHealthy"];
int8_t numAliveLinks = p["numAliveLinks"];
int8_t numTotalLinks = p["numTotalLinks"];
if (isBonded) {
bFoundBond = true;
std::string healthStr;
if (isHealthy) {
healthStr = "HEALTHY";
} else {
healthStr = "DEGRADED";
}
std::string policyStr = "none";
if (bondingPolicy >= ZT_BONDING_POLICY_NONE && bondingPolicy <= ZT_BONDING_POLICY_BALANCE_AWARE) {
policyStr = BondController::getPolicyStrByCode(bondingPolicy);
}
printf("%10s %32s %8s %d/%d" ZT_EOL_S,
OSUtils::jsonString(p ["address"],"-").c_str(),
policyStr.c_str(),
healthStr.c_str(),
numAliveLinks,
numTotalLinks);
}
}
}
if (!bFoundBond) {
printf(" NONE\t\t\t\tNONE\t NONE NONE" ZT_EOL_S);
}
}
return 0;
} else {
printf("%u %s %s" ZT_EOL_S,scode,command.c_str(),responseBody.c_str());
return 1;
}
}
else if (arg1.length() == 10) { /* zerotier-cli bond <peerId> enable */
if (arg2 == "enable") {
fprintf(stderr, "zerotier-cli bond <peerId> enable\n");
return 0;
}
if (arg2 == "rotate") { /* zerotier-cli bond <peerId> rotate */
fprintf(stderr, "zerotier-cli bond <peerId> rotate\n");
requestHeaders["Content-Type"] = "application/json";
requestHeaders["Content-Length"] = "2";
unsigned int scode = Http::POST(
1024 * 1024 * 16,
60000,
(const struct sockaddr *)&addr,
(std::string("/bond/") + arg2 + "/" + arg1).c_str(),
requestHeaders,
"{}",
2,
responseHeaders,
responseBody);
if (scode == 200) {
if (json) {
printf("%s",cliFixJsonCRs(responseBody).c_str());
} else {
printf("200 bond OK" ZT_EOL_S);
}
return 0;
} else {
printf("%u %s %s" ZT_EOL_S,scode,command.c_str(),responseBody.c_str());
return 1;
}
return 0;
}
if (arg2 == "show") {
//fprintf(stderr, "zerotier-cli bond <peerId> show\n");
const unsigned int scode = Http::GET(
1024 * 1024 * 16,60000,
(const struct sockaddr *)&addr,(std::string("/bond/") + arg2 + "/" + arg1).c_str(),
requestHeaders,
responseHeaders,
responseBody);
if (scode == 0) {
printf("Error connecting to the ZeroTier service: %s\n\nPlease check that the service is running and that TCP port 9993 can be contacted via 127.0.0.1." ZT_EOL_S, responseBody.c_str());
return 1;
}
nlohmann::json j;
try {
j = OSUtils::jsonParse(responseBody);
} catch (std::exception &exc) {
printf("%u %s invalid JSON response (%s)" ZT_EOL_S,scode,command.c_str(),exc.what());
return 1;
} catch ( ... ) {
printf("%u %s invalid JSON response (unknown exception)" ZT_EOL_S,scode,command.c_str());
return 1;
}
if (scode == 200) {
if (json) {
printf("%s" ZT_EOL_S,OSUtils::jsonDump(j).c_str());
} else {
bool bFoundBond = false;
std::string healthStr;
if (OSUtils::jsonInt(j["isHealthy"],0)) {
healthStr = "Healthy";
} else {
healthStr = "Degraded";
}
int numAliveLinks = OSUtils::jsonInt(j["numAliveLinks"],0);
int numTotalLinks = OSUtils::jsonInt(j["numTotalLinks"],0);
printf("Peer : %s\n", arg1.c_str());
printf("Bond : %s\n", OSUtils::jsonString(j["bondingPolicy"],"-").c_str());
//if (bondingPolicy == ZT_BONDING_POLICY_ACTIVE_BACKUP) {
printf("Link Select Method : %d\n", OSUtils::jsonInt(j["linkSelectMethod"],0));
//}
printf("Status : %s\n", healthStr.c_str());
printf("Links : %d/%d\n", numAliveLinks, numTotalLinks);
printf("Failover Interval : %d (ms)\n", OSUtils::jsonInt(j["failoverInterval"],0));
printf("Up Delay : %d (ms)\n", OSUtils::jsonInt(j["upDelay"],0));
printf("Down Delay : %d (ms)\n", OSUtils::jsonInt(j["downDelay"],0));
printf("Packets Per Link : %d (ms)\n", OSUtils::jsonInt(j["packetsPerLink"],0));
nlohmann::json &p = j["links"];
if (p.is_array()) {
printf("\n Interface Name\t\t\t\t\t Path\t Alive\n");
for(int i=0; i<80; i++) { printf("-"); }
printf("\n");
for (int i=0; i<p.size(); i++)
{
printf("[%d] %15s %45s %12d\n",
i,
OSUtils::jsonString(p[i]["ifname"],"-").c_str(),
OSUtils::jsonString(p[i]["path"],"-").c_str(),
OSUtils::jsonInt(p[i]["alive"],0));
}
printf("\n Latency Jitter Loss Error Speed Alloc\n");
for(int i=0; i<80; i++) { printf("-"); }
printf("\n");
for (int i=0; i<p.size(); i++)
{
printf("[%d] %5.3f %5.3f %5.3f %5.3f %8d %5d\n",
i,
OSUtils::jsonDouble(p[i]["latencyMean"], 0),
OSUtils::jsonDouble(p[i]["latencyVariance"], 0),
OSUtils::jsonDouble(p[i]["packetLossRatio"], 0),
OSUtils::jsonDouble(p[i]["packetErrorRatio"], 0),
OSUtils::jsonInt(p[i]["givenLinkSpeed"], 0),
OSUtils::jsonInt(p[i]["allocation"], 0));
}
}
}
return 0;
} else {
printf("%u %s %s" ZT_EOL_S,scode,command.c_str(),responseBody.c_str());
return 1;
}
return 2;
}
}
/* zerotier-cli bond command was malformed in some way */
printf("(bond) command is missing required arugments" ZT_EOL_S);
return 2;
const unsigned int scode = Http::GET(1024 * 1024 * 16,60000,(const struct sockaddr *)&addr,"/bonds",requestHeaders,responseHeaders,responseBody);
if (scode == 0) {
printf("Error connecting to the ZeroTier service: %s\n\nPlease check that the service is running and that TCP port 9993 can be contacted via 127.0.0.1." ZT_EOL_S, responseBody.c_str());
return 1;
}
} else if (command == "listbonds") {
const unsigned int scode = Http::GET(1024 * 1024 * 16,60000,(const struct sockaddr *)&addr,"/bonds",requestHeaders,responseHeaders,responseBody);
@ -530,9 +722,9 @@ static int cli(int argc,char **argv)
bFoundBond = true;
std::string healthStr;
if (isHealthy) {
healthStr = "HEALTHY";
healthStr = "Healthy";
} else {
healthStr = "DEGRADED";
healthStr = "Degraded";
}
std::string policyStr = "none";
if (bondingPolicy >= ZT_BONDING_POLICY_NONE && bondingPolicy <= ZT_BONDING_POLICY_BALANCE_AWARE) {
@ -540,7 +732,7 @@ static int cli(int argc,char **argv)
}
printf("%10s %32s %8s %d/%d" ZT_EOL_S,
OSUtils::jsonString(p ["address"],"-").c_str(),
OSUtils::jsonString(p["address"],"-").c_str(),
policyStr.c_str(),
healthStr.c_str(),
numAliveLinks,