eclcmd_common.hpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #ifndef ECLCMD_COMMON_HPP
  14. #define ECLCMD_COMMON_HPP
  15. #include "ws_workunits.hpp"
  16. #include "eclcc.hpp"
  17. //=========================================================================================
  18. enum eclCmdOptionMatchIndicator
  19. {
  20. EclCmdOptionNoMatch=0,
  21. EclCmdOptionMatch=1,
  22. EclCmdOptionCompletion=2
  23. };
  24. interface IEclCommand : extends IInterface
  25. {
  26. virtual eclCmdOptionMatchIndicator parseCommandLineOptions(ArgvIterator &iter)=0;
  27. virtual bool finalizeOptions(IProperties *globals)=0;
  28. virtual int processCMD()=0;
  29. virtual void usage()=0;
  30. };
  31. typedef IEclCommand *(*EclCommandFactory)(const char *cmdname);
  32. #define ECLOPT_HELP "--help"
  33. #define ECLARG_HELP "help"
  34. #define ECLOPT_OUTPUT "--output"
  35. #define ECLOPT_OUTPUT_S "-O"
  36. #define ECLOPT_SERVER "--server"
  37. #define ECLOPT_SERVER_S "-s"
  38. #define ECLOPT_SERVER_INI "eclWatchIP"
  39. #define ECLOPT_SERVER_ENV "ECL_WATCH_IP"
  40. #define ECLOPT_SERVER_DEFAULT "."
  41. #define ECLOPT_SSL "--ssl"
  42. #define ECLOPT_SSL_S "-ssl"
  43. #define ECLOPT_SSL_INI "eclSSL"
  44. #define ECLOPT_SSL_ENV "ECL_SSL"
  45. //The following TLS options could be made more verbose, but these match CURL for convenience
  46. #define ECLOPT_CLIENT_CERT "--cert"
  47. #define ECLOPT_CA_CERT "--cacert"
  48. #define ECLOPT_CLIENT_PRIVATE_KEY "--key"
  49. #define ECLOPT_CLIENT_CERT_INI "eclClientCert"
  50. #define ECLOPT_CLIENT_CERT_ENV "ECL_CLIENT_CERT"
  51. #define ECLOPT_CLIENT_PRIVATE_KEY_INI "eclClientPrivateKey"
  52. #define ECLOPT_CLIENT_PRIVATE_KEY_ENV "ECL_CLIENT_PRIVATE_KEY"
  53. #define ECLOPT_CA_CERT_INI "eclCACert"
  54. #define ECLOPT_CA_CERT_ENV "ECL_CA_CERT"
  55. #define ECLOPT_ACCEPT_SELFSIGNED "--accept-self-signed"
  56. #define ECLOPT_ACCEPT_SELFSIGNED_INI "eclAcceptSelfSigned"
  57. #define ECLOPT_ACCEPT_SELFSIGNED_ENV "ECL_ACCEPT_SELF_SIGNED"
  58. #define ECLOPT_SOURCE_SSL "--source-ssl"
  59. #define ECLOPT_SOURCE_NO_SSL "--source-no-ssl"
  60. #define ECLOPT_PORT "--port"
  61. #define ECLOPT_PORT_INI "eclWatchPort"
  62. #define ECLOPT_PORT_ENV "ECL_WATCH_PORT"
  63. #define ECLOPT_PORT_DEFAULT "8010"
  64. #define ECLOPT_WAIT_CONNECT "--wait-connect"
  65. #define ECLOPT_WAIT_READ "--wait-read"
  66. #define ECLOPT_USERNAME "--username"
  67. #define ECLOPT_USERNAME_S "-u"
  68. #define ECLOPT_USERNAME_INI "eclUserName"
  69. #define ECLOPT_USERNAME_ENV "ECL_USER_NAME"
  70. #define ECLOPT_PASSWORD "--password"
  71. #define ECLOPT_PASSWORD_S "-pw"
  72. #define ECLOPT_PASSWORD_INI "eclPassword"
  73. #define ECLOPT_PASSWORD_ENV "ECL_PASSWORD"
  74. #define ECLOPT_NORELOAD "--no-reload"
  75. #define ECLOPT_NOPUBLISH "--no-publish"
  76. #define ECLOPT_OVERWRITE "--overwrite"
  77. #define ECLOPT_REPLACE "--replace"
  78. #define ECLOPT_OVERWRITE_S "-O"
  79. #define ECLOPT_OVERWRITE_INI "overwriteDefault"
  80. #define ECLOPT_OVERWRITE_ENV NULL
  81. #define ECLOPT_DONT_COPY_FILES "--no-files"
  82. #define ECLOPT_ALLOW_FOREIGN "--allow-foreign"
  83. #define ECLOPT_ACTIVE "--active"
  84. #define ECLOPT_ACTIVE_ONLY "--active-only"
  85. #define ECLOPT_ALL "--all"
  86. #define ECLOPT_INACTIVE "--inactive"
  87. #define ECLOPT_NO_ACTIVATE "--no-activate"
  88. #define ECLOPT_ACTIVATE "--activate"
  89. #define ECLOPT_ACTIVATE_S "-A"
  90. #define ECLOPT_ACTIVATE_INI "activateDefault"
  91. #define ECLOPT_ACTIVATE_ENV NULL
  92. #define ECLOPT_CLONE_ACTIVE_STATE "--clone-active-state"
  93. #define ECLOPT_SUSPEND_PREVIOUS "--suspend-prev"
  94. #define ECLOPT_SUSPEND_PREVIOUS_S "-sp"
  95. #define ECLOPT_SUSPEND_PREVIOUS_INI "suspendPrevDefault"
  96. #define ECLOPT_SUSPEND_PREVIOUS_ENV "ACTIVATE_SUSPEND_PREVIOUS"
  97. #define ECLOPT_DELETE_PREVIOUS "--delete-prev"
  98. #define ECLOPT_DELETE_PREVIOUS_S "-dp"
  99. #define ECLOPT_DELETE_PREVIOUS_INI "deletePrevDefault"
  100. #define ECLOPT_DELETE_PREVIOUS_ENV "ACTIVATE_DELETE_PREVIOUS"
  101. #define ECLOPT_CHECK_DFS "--check-dfs"
  102. #define ECLOPT_UPDATE_DFS "--update-dfs"
  103. #define ECLOPT_GLOBAL_SCOPE "--global-scope"
  104. #define ECLOPT_DELETE_FILES "--delete"
  105. #define ECLOPT_DELETE_SUBFILES "--delete-subfiles"
  106. #define ECLOPT_DELETE_RECURSIVE "--delete-recursive"
  107. #define ECLOPT_RETRY "--retry"
  108. #define ECLOPT_CHECK_ALL_NODES "--check-all-nodes"
  109. #define ECLOPT_CHECK_ALL_NODES_INI "checkAllNodes"
  110. #define ECLOPT_CHECK_ALL_NODES_ENV "CHECK_ALL_NODES"
  111. #define ECLOPT_UPDATE_SUPER_FILES "--update-super-files"
  112. #define ECLOPT_UPDATE_CLONE_FROM "--update-clone-from"
  113. #define ECLOPT_DONT_APPEND_CLUSTER "--dont-append-cluster"
  114. #define ECLOPT_PART_NAME "--part-name"
  115. #define ECLOPT_PROTECT "--protect"
  116. #define ECLOPT_USE_EXISTING "--use-existing"
  117. #define ECLOPT_IGNORE_WARNINGS "--ignore-warnings"
  118. #define ECLOPT_IGNORE_OPTIONAL "--ignore-optional"
  119. #define ECLOPT_IGNORE_QUERIES "--ignore-queries"
  120. #define ECLOPT_MAIN "--main"
  121. #define ECLOPT_MAIN_S "-main" //eclcc compatible format
  122. #define ECLOPT_SNAPSHOT "--snapshot"
  123. #define ECLOPT_SNAPSHOT_S "-sn"
  124. #define ECLOPT_ECL_ONLY "--ecl-only"
  125. #define ECLOPT_WAIT "--wait"
  126. #define ECLOPT_WAIT_INI "waitTimeout"
  127. #define ECLOPT_WAIT_ENV "ECL_WAIT_TIMEOUT"
  128. #define ECLOPT_TIME_LIMIT "--timeLimit"
  129. #define ECLOPT_MEMORY_LIMIT "--memoryLimit"
  130. #define ECLOPT_WARN_TIME_LIMIT "--warnTimeLimit"
  131. #define ECLOPT_PRIORITY "--priority"
  132. #define ECLOPT_COMMENT "--comment"
  133. #define ECLOPT_CHECK_PACKAGEMAPS "--check-packagemaps"
  134. #define ECLOPT_PRELOAD_ALL_PACKAGES "--preload-all"
  135. #define ECLOPT_EXCEPTION_LEVEL "--exception-level"
  136. #define ECLOPT_RESULT_LIMIT "--limit"
  137. #define ECLOPT_RESULT_LIMIT_INI "resultLimit"
  138. #define ECLOPT_RESULT_LIMIT_ENV "ECL_RESULT_LIMIT"
  139. #define ECLOPT_INPUT "--input"
  140. #define ECLOPT_INPUT_S "-in"
  141. #define ECLOPT_NOROOT "--noroot"
  142. #define ECLOPT_POLL "--poll"
  143. #define ECLOPT_WUID "--wuid"
  144. #define ECLOPT_WUID_S "-wu"
  145. #define ECLOPT_CLUSTER_DEPRECATED "--cluster"
  146. #define ECLOPT_CLUSTER_DEPRECATED_S "-cl"
  147. #define ECLOPT_TARGET "--target"
  148. #define ECLOPT_TARGET_S "-t"
  149. #define ECLOPT_NAME "--name"
  150. #define ECLOPT_NAME_S "-n"
  151. #define ECLOPT_JOB_NAME "--job-name"
  152. #define ECLOPT_QUERY_NAME "--query-name"
  153. #define ECLOPT_QUERYSET "--queryset"
  154. #define ECLOPT_QUERYSET_S "-qs"
  155. #define ECLOPT_VERSION "--version"
  156. #define ECLOPT_SHOW "--show"
  157. #define ECLOPT_PMID "--pmid"
  158. #define ECLOPT_PMID_S "-pm"
  159. #define ECLOPT_QUERYID "--queryid"
  160. #define ECLOPT_QUERIES "--queries"
  161. #define ECLOPT_QUERYIDS "--queryids"
  162. #define ECLOPT_DALIIP "--daliip"
  163. #define ECLOPT_PROCESS "--process"
  164. #define ECLOPT_PROCESS_S "-p"
  165. #define ECLOPT_SOURCE_PROCESS "--source-process"
  166. #define ECLOPT_PATH "--path"
  167. #define ECLOPT_INC_THOR_SLAVE_LOGS "--inc-thor-slave-logs"
  168. #define ECLOPT_PROBLEM_DESC "--description"
  169. #define ECLOPT_CREATE_DIRS "--create-dirs"
  170. #define ECLOPT_LIB_PATH_S "-L"
  171. #define ECLOPT_IMP_PATH_S "-I"
  172. #define ECLOPT_MANIFEST "--manifest"
  173. #define ECLOPT_MANIFEST_DASH "-manifest"
  174. #define ECLOPT_LEGACY "--legacy"
  175. #define ECLOPT_LEGACY_DASH "-legacy"
  176. #define ECLOPT_CHECKDIRTY "-checkDirty"
  177. #define ECLOPT_DEBUG "--debug"
  178. #define ECLOPT_DEBUG_DASH "-g"
  179. #define ECLOPT_FAST_SYNTAX "--fastsyntax"
  180. #define ECLOPT_NO_STD_INC "--nostdinc"
  181. #define ECLOPT_FETCH_REPOS "--fetchrepos"
  182. #define ECLOPT_UPDATE_REPOS "--updaterepos"
  183. #define ECLOPT_DEFAULT_GIT_PREFIX "--defaultgitprefix"
  184. #define ECLOPT_REPO_MAPPING "-R"
  185. #define ECLOPT_VERBOSE "--verbose"
  186. #define ECLOPT_VERBOSE_S "-v"
  187. #define ECLOPT_KEYUID "--keyuid"
  188. #define ECLOPT_KEYPASS "--keypass"
  189. const char *queryEclccPath(bool optVerbose);
  190. bool extractEclCmdOption(StringBuffer & option, IProperties * globals, const char * envName, const char * propertyName, const char * defaultPrefix, const char * defaultSuffix);
  191. bool extractEclCmdOption(StringAttr & option, IProperties * globals, const char * envName, const char * propertyName, const char * defaultPrefix, const char * defaultSuffix);
  192. bool extractEclCmdOption(bool & option, IProperties * globals, const char * envName, const char * propertyName, bool defval);
  193. bool extractEclCmdOption(unsigned & option, IProperties * globals, const char * envName, const char * propertyName, unsigned defval);
  194. bool matchVariableOption(ArgvIterator &iter, const char prefix, IArrayOf<IEspNamedValue> &values, bool expandEclccOptions);
  195. void addNamedValue(const char * name, const char * value, IArrayOf<IEspNamedValue> &values);
  196. enum eclObjParameterType
  197. {
  198. eclObjTypeUnknown = 0x00,
  199. eclObjSource = 0x01,
  200. eclObjArchive = 0x02,
  201. eclObjSharedObject = 0x04,
  202. eclObjWuid = 0x08,
  203. eclObjQuery = 0x10,
  204. eclObjManifest = 0x20
  205. };
  206. #define eclObjSourceOrArchive (eclObjSource|eclObjArchive)
  207. class EclObjectParameter
  208. {
  209. public:
  210. EclObjectParameter(unsigned _accept=0x00);
  211. eclObjParameterType set(const char *_value);
  212. const char *queryTypeName();
  213. StringBuffer &getDescription(StringBuffer &s);
  214. void loadStdIn();
  215. void loadFile();
  216. eclObjParameterType finalizeContentType();
  217. bool isElfContent();
  218. bool isPEContent();
  219. void ensureUtf8Content();
  220. public:
  221. eclObjParameterType type;
  222. StringAttr value;
  223. StringAttr query;
  224. MemoryBuffer mb;
  225. unsigned accept;
  226. };
  227. class EclCmdCommon : implements IEclCommand, public CInterface
  228. {
  229. public:
  230. IMPLEMENT_IINTERFACE;
  231. EclCmdCommon(bool _usesESP=true) : optVerbose(false), optSSL(false), usesESP(_usesESP)
  232. {
  233. }
  234. virtual eclCmdOptionMatchIndicator matchCommandLineOption(ArgvIterator &iter, bool finalAttempt=false);
  235. virtual bool finalizeOptions(IProperties *globals);
  236. inline void setRpcOptions(IEspClientRpcSettings &rpc, unsigned int waitMS = 0)
  237. {
  238. setRpcRequestTimeouts(rpc, waitMS, optWaitConnectMs, optWaitReadSec);
  239. setRpcSSLOptions(rpc, optSSL, optClientCert, optClientPrivateKey, optCACert, optAcceptSelfSigned);
  240. }
  241. virtual void usage()
  242. {
  243. fprintf(stdout,
  244. " --help Display usage information for the given command\n"
  245. " -v, --verbose Output additional tracing information\n"
  246. );
  247. if (usesESP)
  248. fprintf(stdout,
  249. " -s, --server=<ip> IP of server running ecl services (eclwatch)\n"
  250. " -ssl, --ssl Use SSL to secure the connection to the server(s)\n"
  251. " --accept-self-signed Allow SSL servers to use self signed certificates\n"
  252. " --cert Path to file containing SSL client certificate\n"
  253. " --key Path to file containing SSL client certificate private key\n"
  254. " --cacert Path to file containing SSL CA certificate\n"
  255. " --port=<port> ECL services port\n"
  256. " -u, --username=<name> Username for accessing ecl services\n"
  257. " -pw, --password=<pw> Password for accessing ecl services\n"
  258. " --wait-connect=<Ms> Timeout while connecting to server (in milliseconds)\n"
  259. " --wait-read=<Sec> Timeout while reading from socket (in seconds)\n"
  260. );
  261. }
  262. public:
  263. StringAttr optServer;
  264. StringAttr optPort;
  265. StringAttr optUsername;
  266. StringAttr optPassword;
  267. StringAttr optClientCert;
  268. StringAttr optClientPrivateKey;
  269. StringAttr optCACert;
  270. bool optPasswordProvided = false;
  271. unsigned optWaitConnectMs = 0;
  272. unsigned optWaitReadSec = 0;
  273. bool optVerbose;
  274. bool optSSL;
  275. bool sslOptProvided = false;
  276. bool optAcceptSelfSigned = false;
  277. bool selfsignedOptProvided = false;
  278. bool usesESP;
  279. };
  280. class EclCmdWithEclTarget : public EclCmdCommon
  281. {
  282. public:
  283. EclCmdWithEclTarget() : optLegacy(false), optCheckDirty(false), optNoArchive(false), optResultLimit((unsigned)-1), optDebug(false), paramCount(0)
  284. {
  285. }
  286. virtual eclCmdOptionMatchIndicator matchCommandLineOption(ArgvIterator &iter, bool finalAttempt=false);
  287. virtual bool finalizeOptions(IProperties *globals);
  288. bool setTarget(const char *target);
  289. bool setParam(const char *in, bool final);
  290. virtual void usage()
  291. {
  292. EclCmdCommon::usage();
  293. fprintf(stdout,
  294. " --main=<definition> Definition to use from legacy ECL repository\n"
  295. " --snapshot,-sn=<label> Snapshot label to use from legacy ECL repository\n"
  296. " --ecl-only Send ECL query to HPCC as text rather than as a generated archive\n"
  297. " --limit=<limit> Sets the result limit for the query\n"
  298. " -f<option>[=value] Set an ECL language option (equivalent to #option)\n"
  299. " -f-<option>[=value] Set an eclcc command line option (single '-')\n"
  300. " -f--<option>[=value] Set an eclcc command line option (double '-')\n"
  301. " -Dname=value Override the definition of a global attribute 'name'\n"
  302. " eclcc options (everything following):\n"
  303. );
  304. for (unsigned line=0; line < _elements_in(helpText); line++)
  305. {
  306. const char * text = helpText[line];
  307. StringBuffer wsPrefix;
  308. if (*text == '?')
  309. {
  310. text = text+1;
  311. if (*text != ' ')
  312. wsPrefix.append(' ');
  313. }
  314. else
  315. continue;
  316. if (*text == '!')
  317. {
  318. if (optVerbose)
  319. {
  320. text = text+1;
  321. fprintf(stdout, "%s%s\n", wsPrefix.str(), text);
  322. }
  323. }
  324. else
  325. fprintf(stdout, "%s%s\n", wsPrefix.str(), text);
  326. }
  327. }
  328. public:
  329. StringAttr param;
  330. StringAttr optTargetCluster;
  331. EclObjectParameter optObj;
  332. StringBuffer optLibPath;
  333. StringBuffer optImpPath;
  334. StringAttr optManifest;
  335. StringAttr optAttributePath;
  336. StringAttr optSnapshot;
  337. IArrayOf<IEspNamedValue> debugValues;
  338. IArrayOf<IEspNamedValue> definitions;
  339. unsigned optResultLimit;
  340. unsigned paramCount;
  341. bool optNoArchive;
  342. bool optLegacy;
  343. bool optDebug;
  344. bool optCheckDirty;
  345. bool optFastSyntax = false;
  346. bool optNoStdInc = false;
  347. StringArray extraOptions;
  348. };
  349. class EclCmdWithQueryTarget : public EclCmdCommon
  350. {
  351. public:
  352. EclCmdWithQueryTarget()
  353. {
  354. }
  355. virtual eclCmdOptionMatchIndicator matchCommandLineOption(ArgvIterator &iter, bool finalAttempt=false);
  356. virtual bool finalizeOptions(IProperties *globals);
  357. virtual eclCmdOptionMatchIndicator parseCommandLineOptions(ArgvIterator &iter);
  358. virtual void usage()
  359. {
  360. EclCmdCommon::usage();
  361. }
  362. public:
  363. StringAttr optQuerySet;
  364. StringAttr optQuery;
  365. };
  366. void outputExceptionEx(IException &e);
  367. int outputMultiExceptionsEx(const IMultiException &me);
  368. bool checkMultiExceptionsQueryNotFound(const IMultiException &me);
  369. bool outputQueryFileCopyErrors(IArrayOf<IConstLogicalFileError> &errors);
  370. class EclCmdURL : public StringBuffer
  371. {
  372. public:
  373. EclCmdURL(const char *service, const char *ip, const char *port, bool ssl, const char *tail=NULL)
  374. {
  375. set("http");
  376. if (ssl)
  377. append('s');
  378. append("://").append(ip).append(':').append(port).append('/').append(service);
  379. if (tail)
  380. append(tail);
  381. }
  382. };
  383. template <class Iface> Iface *intClient(Iface *client, EclCmdCommon &cmd, const char *service, const char *urlTail)
  384. {
  385. if(cmd.optServer.isEmpty())
  386. throw MakeStringException(-1, "Server IP not specified");
  387. EclCmdURL url(service, cmd.optServer, cmd.optPort, cmd.optSSL, urlTail);
  388. client->addServiceUrl(url.str());
  389. if (cmd.optUsername.length())
  390. client->setUsernameToken(cmd.optUsername, cmd.optPassword, NULL);
  391. return client;
  392. }
  393. #define createCmdClient(SN, cmd) intClient<IClient##SN>(create##SN##Client(), cmd, #SN, NULL);
  394. #define createCmdClientExt(SN, cmd, urlTail) intClient<IClient##SN>(create##SN##Client(), cmd, #SN, urlTail);
  395. #endif