Compare commits

..

2 Commits

Author SHA1 Message Date
Vitaliy Filippov 244aaa414a Add client docs to readme 2024-06-01 15:08:38 +03:00
Vitaliy Filippov 8c4bbf11d5 Add TLS cert/key support to cli 2024-06-01 15:08:08 +03:00
3 changed files with 61 additions and 17 deletions

View File

@ -16,6 +16,7 @@ License: Mozilla Public License 2.0 or [VNPL-1.1](https://git.yourcmc.ru/vitalif
# Contents # Contents
- [CLI Usage](#cli-usage) - [CLI Usage](#cli-usage)
- [CLI Client](#cli-client)
- [Options](#options) - [Options](#options)
- [HTTP](#http) - [HTTP](#http)
- [Persistence](#persistence) - [Persistence](#persistence)
@ -47,6 +48,34 @@ node_modules/.bin/antietcd \
Antietcd doesn't background itself, so use systemd or start-stop-daemon to run it as a background service. Antietcd doesn't background itself, so use systemd or start-stop-daemon to run it as a background service.
### CLI Client
```
node_modules/.bin/anticli [OPTIONS] put <key> [<value>]
node_modules/.bin/anticli [OPTIONS] get <key> [-p|--prefix] [-v|--print-value-only] [-k|--keys-only]
node_modules/.bin/anticli [OPTIONS] del <key> [-p|--prefix]
```
For `put`, if `<value>` is not specified, it will be read from STDIN.
Options:
<dl>
<dt>--endpoints|-e http://node1:2379,http://node2:2379,http://node3:2379</dt>
<dd>Specify HTTP endpoints to connect to</dd>
<dt>--cert &lt;cert&gt;</dt>
<dd>Use TLS with this certificate file (PEM format)</dd>
<dt>--key &lt;key&gt;</dt>
<dd>Use TLS with this key file (PEM format)</dd>
<dt>--timeout 1000</dt>
<dd>Specify request timeout in milliseconds</dd>
</dl>
## Options ## Options
### HTTP ### HTTP

View File

@ -4,6 +4,22 @@ const fsp = require('fs').promises;
const http = require('http'); const http = require('http');
const https = require('https'); const https = require('https');
const help_text = `CLI for AntiEtcd
(c) Vitaliy Filippov, 2024
License: Mozilla Public License 2.0 or Vitastor Network Public License 1.1
Usage:
anticli.js [OPTIONS] put <key> [<value>]
anticli.js [OPTIONS] get <key> [-p|--prefix] [-v|--print-value-only] [-k|--keys-only]
anticli.js [OPTIONS] del <key> [-p|--prefix]
Options:
[--endpoints|-e http://node1:2379,http://node2:2379,http://node3:2379]
[--cert cert.pem] [--key key.pem] [--timeout 1000]
`;
class AntiEtcdCli class AntiEtcdCli
{ {
static parse(args) static parse(args)
@ -15,15 +31,7 @@ class AntiEtcdCli
const arg = args[i].toLowerCase().replace(/^--(.+)$/, (m, m1) => '--'+m1.replace(/-/g, '_')); const arg = args[i].toLowerCase().replace(/^--(.+)$/, (m, m1) => '--'+m1.replace(/-/g, '_'));
if (arg === '-h' || arg === '--help') if (arg === '-h' || arg === '--help')
{ {
process.stderr.write( process.stderr.write(help_text);
'USAGE:\n'+
' anticli.js [OPTIONS] put <key> [<value>]\n'+
' anticli.js [OPTIONS] get <key> [-p|--prefix] [-v|--print-value-only] [-k|--keys-only]\n'+
' anticli.js [OPTIONS] del <key> [-p|--prefix]\n'+
'OPTIONS:\n'+
' [--endpoints|-e http://node1:2379,http://node2:2379,http://node3:2379]\n'+
' [--timeout 1000]'
);
process.exit(); process.exit();
} }
else if (arg == '-e' || arg == '--endpoints') else if (arg == '-e' || arg == '--endpoints')
@ -71,6 +79,13 @@ class AntiEtcdCli
{ {
this.options.endpoints = [ 'http://localhost:2379' ]; this.options.endpoints = [ 'http://localhost:2379' ];
} }
if (this.options.cert && this.options.key)
{
this.tls = {
key: await fsp.readFile(this.options.key),
cert: await fsp.readFile(this.options.cert),
};
}
if (cmd[0] == 'get') if (cmd[0] == 'get')
{ {
await this.get(cmd.slice(1)); await this.get(cmd.slice(1));
@ -151,7 +166,7 @@ class AntiEtcdCli
for (const url of this.options.endpoints) for (const url of this.options.endpoints)
{ {
const cur_url = url.replace(/\/+$/, '')+path; const cur_url = url.replace(/\/+$/, '')+path;
const res = await POST(cur_url, body, this.options.timeout||1000); const res = await POST(cur_url, this.tls||{}, body, this.options.timeout||1000);
if (res.json) if (res.json)
{ {
if (res.json.error) if (res.json.error)
@ -180,7 +195,7 @@ class AntiEtcdCli
} }
} }
function POST(url, body, timeout) function POST(url, options, body, timeout)
{ {
return new Promise(ok => return new Promise(ok =>
{ {
@ -195,7 +210,7 @@ function POST(url, body, timeout)
let req = (url.substr(0, 6).toLowerCase() == 'https://' ? https : http).request(url, { method: 'POST', headers: { let req = (url.substr(0, 6).toLowerCase() == 'https://' ? https : http).request(url, { method: 'POST', headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Content-Length': body_text.length, 'Content-Length': body_text.length,
} }, (res) => }, timeout, ...options }, (res) =>
{ {
if (!req) if (!req)
{ {

View File

@ -8,10 +8,10 @@ License: Mozilla Public License 2.0 or Vitastor Network Public License 1.1
Usage: Usage:
${process.argv[0]} ${process.argv[1]} ${process.argv[0]} ${process.argv[1]} \
[--cert ssl.crt] [--key ssl.key] [--port 12379] [--cert ssl.crt] [--key ssl.key] [--port 12379] \
[--data data.gz] [--persist-filter ./filter.js] [--persist_interval 500] [--data data.gz] [--persist-filter ./filter.js] [--persist_interval 500] \
[--node_id node1 --cluster_key abcdef --cluster node1=http://localhost:12379,node2=http://localhost:12380,node3=http://localhost:12381] [--node_id node1 --cluster_key abcdef --cluster node1=http://localhost:12379,node2=http://localhost:12380,node3=http://localhost:12381] \
[other options] [other options]
Supported etcd REST APIs: Supported etcd REST APIs:
@ -91,7 +91,7 @@ function parse()
const arg = process.argv[i].toLowerCase().replace(/^--(.+)$/, (m, m1) => '--'+m1.replace(/-/g, '_')); const arg = process.argv[i].toLowerCase().replace(/^--(.+)$/, (m, m1) => '--'+m1.replace(/-/g, '_'));
if (arg === '-h' || arg === '--help') if (arg === '-h' || arg === '--help')
{ {
console.error(help_text.trim()); process.stderr.write(help_text);
process.exit(); process.exit();
} }
else if (arg.substr(0, 2) == '--') else if (arg.substr(0, 2) == '--')