mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-01-18 10:46:33 +00:00
Basic CLI working with JSON output. Now to parse and support old tabular form.
This commit is contained in:
parent
53cbe485f0
commit
8333bf065e
@ -61,6 +61,7 @@ one: $(OBJS) one.o
|
|||||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o zerotier-one $(OBJS) one.o $(LIBS)
|
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o zerotier-one $(OBJS) one.o $(LIBS)
|
||||||
$(STRIP) zerotier-one
|
$(STRIP) zerotier-one
|
||||||
ln -sf zerotier-one zerotier-idtool
|
ln -sf zerotier-one zerotier-idtool
|
||||||
|
ln -sf zerotier-one zerotier-cli
|
||||||
|
|
||||||
selftest: $(OBJS) selftest.o
|
selftest: $(OBJS) selftest.o
|
||||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o zerotier-selftest selftest.o $(OBJS) $(LIBS)
|
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o zerotier-selftest selftest.o $(OBJS) $(LIBS)
|
||||||
|
@ -67,6 +67,7 @@ one: $(OBJS) one.o
|
|||||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o zerotier-one $(OBJS) one.o $(LIBS)
|
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o zerotier-one $(OBJS) one.o $(LIBS)
|
||||||
$(STRIP) zerotier-one
|
$(STRIP) zerotier-one
|
||||||
ln -sf zerotier-one zerotier-idtool
|
ln -sf zerotier-one zerotier-idtool
|
||||||
|
ln -sf zerotier-one zerotier-cli
|
||||||
|
|
||||||
selftest: $(OBJS) selftest.o
|
selftest: $(OBJS) selftest.o
|
||||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o zerotier-selftest selftest.o $(OBJS) $(LIBS)
|
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o zerotier-selftest selftest.o $(OBJS) $(LIBS)
|
||||||
|
@ -56,6 +56,7 @@ one: $(OBJS) one.o
|
|||||||
$(CXX) $(CXXFLAGS) -o zerotier-one $(OBJS) one.o $(LIBS)
|
$(CXX) $(CXXFLAGS) -o zerotier-one $(OBJS) one.o $(LIBS)
|
||||||
$(STRIP) zerotier-one
|
$(STRIP) zerotier-one
|
||||||
ln -sf zerotier-one zerotier-idtool
|
ln -sf zerotier-one zerotier-idtool
|
||||||
|
ln -sf zerotier-one zerotier-cli
|
||||||
|
|
||||||
selftest: $(OBJS) selftest.o
|
selftest: $(OBJS) selftest.o
|
||||||
$(CXX) $(CXXFLAGS) -o zerotier-selftest selftest.o $(OBJS) $(LIBS)
|
$(CXX) $(CXXFLAGS) -o zerotier-selftest selftest.o $(OBJS) $(LIBS)
|
||||||
|
229
one.cpp
229
one.cpp
@ -63,6 +63,7 @@
|
|||||||
#include "node/Utils.hpp"
|
#include "node/Utils.hpp"
|
||||||
#include "node/NetworkController.hpp"
|
#include "node/NetworkController.hpp"
|
||||||
#include "osdep/OSUtils.hpp"
|
#include "osdep/OSUtils.hpp"
|
||||||
|
#include "osdep/Http.hpp"
|
||||||
#include "service/OneService.hpp"
|
#include "service/OneService.hpp"
|
||||||
#ifdef ZT_ENABLE_NETWORK_CONTROLLER
|
#ifdef ZT_ENABLE_NETWORK_CONTROLLER
|
||||||
#include "controller/SqliteNetworkController.hpp"
|
#include "controller/SqliteNetworkController.hpp"
|
||||||
@ -79,12 +80,229 @@ static OneService *volatile zt1Service = (OneService *)0;
|
|||||||
/* zerotier-cli personality */
|
/* zerotier-cli personality */
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
||||||
|
static void cliPrintHelp(const char *pn,FILE *out)
|
||||||
|
{
|
||||||
|
fprintf(out,"ZeroTier One version %d.%d.%d"ZT_EOL_S"(c)2011-2015 ZeroTier, Inc."ZT_EOL_S,ZEROTIER_ONE_VERSION_MAJOR,ZEROTIER_ONE_VERSION_MINOR,ZEROTIER_ONE_VERSION_REVISION);
|
||||||
|
fprintf(out,"Licensed under the GNU General Public License v3"ZT_EOL_S""ZT_EOL_S);
|
||||||
|
fprintf(out,"Usage: %s [-switches] <command/path> [<args>]"ZT_EOL_S""ZT_EOL_S,pn);
|
||||||
|
fprintf(out,"Available switches:"ZT_EOL_S);
|
||||||
|
fprintf(out," -h - Display this help"ZT_EOL_S);
|
||||||
|
fprintf(out," -v - Show version"ZT_EOL_S);
|
||||||
|
fprintf(out," -j - Display full raw JSON output"ZT_EOL_S);
|
||||||
|
fprintf(out," -D<path> - ZeroTier home path for parameter auto-detect"ZT_EOL_S);
|
||||||
|
fprintf(out," -p<port> - HTTP port (default: auto)"ZT_EOL_S);
|
||||||
|
fprintf(out," -T<token> - Authentication token (default: auto)"ZT_EOL_S);
|
||||||
|
fprintf(out," -H<ip> - HTTP IP address (default: 127.0.0.1)"ZT_EOL_S""ZT_EOL_S);
|
||||||
|
fprintf(out,"Available commands:"ZT_EOL_S);
|
||||||
|
fprintf(out," info - Display status info"ZT_EOL_S);
|
||||||
|
fprintf(out," listpeers - List all peers"ZT_EOL_S);
|
||||||
|
fprintf(out," listnetworks - List all networks"ZT_EOL_S);
|
||||||
|
fprintf(out," join <network> - Join a network"ZT_EOL_S);
|
||||||
|
fprintf(out," leave <network> - Leave a network"ZT_EOL_S);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string cliFixJsonCRs(const std::string &s)
|
||||||
|
{
|
||||||
|
std::string r;
|
||||||
|
for(std::string::const_iterator c(s.begin());c!=s.end();++c) {
|
||||||
|
if (*c == '\n')
|
||||||
|
r.append(ZT_EOL_S);
|
||||||
|
else r.push_back(*c);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
static int cli(int argc, _TCHAR* argv[])
|
static int cli(int argc, _TCHAR* argv[])
|
||||||
#else
|
#else
|
||||||
static int cli(int argc,char **argv)
|
static int cli(int argc,char **argv)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
unsigned int port = 0;
|
||||||
|
std::string homeDir;
|
||||||
|
std::string command;
|
||||||
|
std::string arg1;
|
||||||
|
std::string authToken;
|
||||||
|
std::string ip("127.0.0.1");
|
||||||
|
bool json = false;
|
||||||
|
for(int i=1;i<argc;++i) {
|
||||||
|
if (argv[i][0] == '-') {
|
||||||
|
switch(argv[i][1]) {
|
||||||
|
|
||||||
|
case 'q': // ignore -q used to invoke this personality
|
||||||
|
if (argv[i][2]) {
|
||||||
|
cliPrintHelp(argv[0],stdout);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'j':
|
||||||
|
if (argv[i][2]) {
|
||||||
|
cliPrintHelp(argv[0],stdout);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
json = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'p': // port for HTTP
|
||||||
|
port = Utils::strToUInt(argv[i] + 2);
|
||||||
|
if ((port > 0xffff)||(port == 0)) {
|
||||||
|
cliPrintHelp(argv[0],stdout);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'D': // Home path
|
||||||
|
if (argv[i][2]) {
|
||||||
|
homeDir = argv[i] + 2;
|
||||||
|
} else {
|
||||||
|
cliPrintHelp(argv[0],stdout);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'H': // HTTP IP
|
||||||
|
if (argv[i][2]) {
|
||||||
|
ip = argv[i] + 2;
|
||||||
|
} else {
|
||||||
|
cliPrintHelp(argv[0],stdout);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'T': // Override root topology
|
||||||
|
if (argv[i][2]) {
|
||||||
|
authToken = argv[i] + 2;
|
||||||
|
} else {
|
||||||
|
cliPrintHelp(argv[0],stdout);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'v': // Display version
|
||||||
|
if (argv[i][2]) {
|
||||||
|
cliPrintHelp(argv[0],stdout);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
printf("%d.%d.%d"ZT_EOL_S,ZEROTIER_ONE_VERSION_MAJOR,ZEROTIER_ONE_VERSION_MINOR,ZEROTIER_ONE_VERSION_REVISION);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case 'h':
|
||||||
|
case '?':
|
||||||
|
default:
|
||||||
|
cliPrintHelp(argv[0],stdout);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (command.length())
|
||||||
|
arg1 = argv[i];
|
||||||
|
else command = argv[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!homeDir.length())
|
||||||
|
homeDir = OneService::platformDefaultHomePath();
|
||||||
|
|
||||||
|
if ((!port)||(!authToken.length())) {
|
||||||
|
if (!homeDir.length()) {
|
||||||
|
fprintf(stderr,"%s: missing port or authentication token and no home directory specified to auto-detect"ZT_EOL_S,argv[0]);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!port) {
|
||||||
|
std::string portStr;
|
||||||
|
OSUtils::readFile((homeDir + ZT_PATH_SEPARATOR_S + "zerotier-one.port").c_str(),portStr);
|
||||||
|
port = Utils::strToUInt(portStr.c_str());
|
||||||
|
if ((port == 0)||(port > 0xffff)) {
|
||||||
|
fprintf(stderr,"%s: missing port and zerotier-one.port not found in %s"ZT_EOL_S,argv[0],homeDir.c_str());
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!authToken.length()) {
|
||||||
|
OSUtils::readFile((homeDir + ZT_PATH_SEPARATOR_S + "authtoken.secret").c_str(),authToken);
|
||||||
|
if (!authToken.length()) {
|
||||||
|
fprintf(stderr,"%s: missing authentication token and authtoken.secret not found (or readable) in %s"ZT_EOL_S,argv[0],homeDir.c_str());
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InetAddress addr;
|
||||||
|
{
|
||||||
|
char addrtmp[256];
|
||||||
|
Utils::snprintf(addrtmp,sizeof(addrtmp),"%s/%u",ip.c_str(),port);
|
||||||
|
addr = InetAddress(addrtmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string,std::string> requestHeaders;
|
||||||
|
std::map<std::string,std::string> responseHeaders;
|
||||||
|
std::string responseBody;
|
||||||
|
|
||||||
|
requestHeaders["X-ZT1-Auth"] = authToken;
|
||||||
|
|
||||||
|
if ((command == "info")||(command == "status")) {
|
||||||
|
unsigned int scode = Http::GET(
|
||||||
|
1024 * 1024 * 16,
|
||||||
|
60000,
|
||||||
|
(const struct sockaddr *)&addr,
|
||||||
|
"/status",
|
||||||
|
requestHeaders,
|
||||||
|
responseHeaders,
|
||||||
|
responseBody);
|
||||||
|
if (scode == 200) {
|
||||||
|
if (json) {
|
||||||
|
printf("%s",cliFixJsonCRs(responseBody).c_str());
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("%u %s %s"ZT_EOL_S,scode,command.c_str(),responseBody.c_str());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else if (command == "listpeers") {
|
||||||
|
unsigned int scode = Http::GET(
|
||||||
|
1024 * 1024 * 16,
|
||||||
|
60000,
|
||||||
|
(const struct sockaddr *)&addr,
|
||||||
|
"/peer",
|
||||||
|
requestHeaders,
|
||||||
|
responseHeaders,
|
||||||
|
responseBody);
|
||||||
|
if (scode == 200) {
|
||||||
|
if (json) {
|
||||||
|
printf("%s",cliFixJsonCRs(responseBody).c_str());
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("%u %s %s"ZT_EOL_S,scode,command.c_str(),responseBody.c_str());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else if (command == "listnetworks") {
|
||||||
|
unsigned int scode = Http::GET(
|
||||||
|
1024 * 1024 * 16,
|
||||||
|
60000,
|
||||||
|
(const struct sockaddr *)&addr,
|
||||||
|
"/network",
|
||||||
|
requestHeaders,
|
||||||
|
responseHeaders,
|
||||||
|
responseBody);
|
||||||
|
if (scode == 200) {
|
||||||
|
if (json) {
|
||||||
|
printf("%s",cliFixJsonCRs(responseBody).c_str());
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("%u %s %s"ZT_EOL_S,scode,command.c_str(),responseBody.c_str());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else if (command == "join") {
|
||||||
|
} else if (command == "leave") {
|
||||||
|
} else {
|
||||||
|
cliPrintHelp(argv[0],stderr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
@ -93,6 +311,8 @@ static int cli(int argc,char **argv)
|
|||||||
|
|
||||||
static void idtoolPrintHelp(FILE *out,const char *pn)
|
static void idtoolPrintHelp(FILE *out,const char *pn)
|
||||||
{
|
{
|
||||||
|
fprintf(out,"ZeroTier One version %d.%d.%d"ZT_EOL_S"(c)2011-2015 ZeroTier, Inc."ZT_EOL_S,ZEROTIER_ONE_VERSION_MAJOR,ZEROTIER_ONE_VERSION_MINOR,ZEROTIER_ONE_VERSION_REVISION);
|
||||||
|
fprintf(out,"Licensed under the GNU General Public License v3"ZT_EOL_S""ZT_EOL_S);
|
||||||
fprintf(out,"Usage: %s <command> [<args>]"ZT_EOL_S""ZT_EOL_S"Commands:"ZT_EOL_S,pn);
|
fprintf(out,"Usage: %s <command> [<args>]"ZT_EOL_S""ZT_EOL_S"Commands:"ZT_EOL_S,pn);
|
||||||
fprintf(out," generate [<identity.secret>] [<identity.public>]"ZT_EOL_S);
|
fprintf(out," generate [<identity.secret>] [<identity.public>]"ZT_EOL_S);
|
||||||
fprintf(out," validate <identity.secret/public>"ZT_EOL_S);
|
fprintf(out," validate <identity.secret/public>"ZT_EOL_S);
|
||||||
@ -445,6 +665,7 @@ static void printHelp(const char *cn,FILE *out)
|
|||||||
fprintf(out," -d - Fork and run as daemon (Unix-ish OSes)"ZT_EOL_S);
|
fprintf(out," -d - Fork and run as daemon (Unix-ish OSes)"ZT_EOL_S);
|
||||||
#endif // __UNIX_LIKE__
|
#endif // __UNIX_LIKE__
|
||||||
fprintf(out," -i - Generate and manage identities (zerotier-idtool)"ZT_EOL_S);
|
fprintf(out," -i - Generate and manage identities (zerotier-idtool)"ZT_EOL_S);
|
||||||
|
fprintf(out," -q - Query API (zerotier-cli)"ZT_EOL_S);
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
fprintf(out," -C - Run from command line instead of as service (Windows)"ZT_EOL_S);
|
fprintf(out," -C - Run from command line instead of as service (Windows)"ZT_EOL_S);
|
||||||
fprintf(out," -I - Install Windows service (Windows)"ZT_EOL_S);
|
fprintf(out," -I - Install Windows service (Windows)"ZT_EOL_S);
|
||||||
@ -496,6 +717,8 @@ int main(int argc,char **argv)
|
|||||||
|
|
||||||
if ((strstr(argv[0],"zerotier-idtool"))||(strstr(argv[0],"ZEROTIER-IDTOOL")))
|
if ((strstr(argv[0],"zerotier-idtool"))||(strstr(argv[0],"ZEROTIER-IDTOOL")))
|
||||||
return idtool(argc,argv);
|
return idtool(argc,argv);
|
||||||
|
if ((strstr(argv[0],"zerotier-cli"))||(strstr(argv[0],"ZEROTIER-CLI")))
|
||||||
|
return cli(argc,argv);
|
||||||
|
|
||||||
std::string overrideRootTopology;
|
std::string overrideRootTopology;
|
||||||
std::string homeDir;
|
std::string homeDir;
|
||||||
@ -541,6 +764,12 @@ int main(int argc,char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
} else return idtool(argc,argv);
|
} else return idtool(argc,argv);
|
||||||
|
|
||||||
|
case 'q': // Invoke cli personality
|
||||||
|
if (argv[i][2]) {
|
||||||
|
printHelp(argv[0],stdout);
|
||||||
|
return 0;
|
||||||
|
} else return cli(argc,argv);
|
||||||
|
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
case 'C': // Run from command line instead of as Windows service
|
case 'C': // Run from command line instead of as Windows service
|
||||||
winRunFromCommandLine = true;
|
winRunFromCommandLine = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user