tatnet 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +169 -0
- package/bin/tatnet.js +96 -0
- package/package.json +38 -0
package/README.md
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# tatnet — консольный клиент TatNet
|
|
2
|
+
|
|
3
|
+
`tatnet` управляет облаком TatNet из терминала: виртуальные машины,
|
|
4
|
+
приложения, базы Postgres и Valkey, DNS, объектное хранилище, SSH-ключи.
|
|
5
|
+
|
|
6
|
+
Построен поверх [tatnet-go](https://github.com/tatnet-ru/tatnet-go) —
|
|
7
|
+
клиента, генерируемого из контракта `/v1`. Рукописного HTTP здесь нет, и
|
|
8
|
+
контракт — тот же самый документ, что публикует API.
|
|
9
|
+
|
|
10
|
+
## Установка
|
|
11
|
+
|
|
12
|
+
Без установки вообще — если есть Node:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npx tatnet vm list
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Постоянно:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm i -g tatnet
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Бинарник качается не при установке, а приезжает готовым подпакетом на вашу
|
|
25
|
+
платформу (`optionalDependencies` с полями `os`/`cpu`), поэтому работает и
|
|
26
|
+
под `--ignore-scripts`, и из офлайн-кэша. Поддержаны linux, macOS и Windows
|
|
27
|
+
на x64 и arm64.
|
|
28
|
+
|
|
29
|
+
Бинарником с [релизов](https://github.com/tatnet-ru/tatnet-cli/releases)
|
|
30
|
+
(файлы несут номер версии, подставьте свою):
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
VER=0.1.3
|
|
34
|
+
curl -sSL "https://github.com/tatnet-ru/tatnet-cli/releases/download/v$VER/tatnet_${VER}_linux_amd64.tar.gz" | tar xz
|
|
35
|
+
sudo install tatnet /usr/local/bin/
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Либо пакетом — `tatnet_${VER}_linux_amd64.deb` / `.rpm`. Рядом с
|
|
39
|
+
артефактами лежит `checksums.txt`.
|
|
40
|
+
|
|
41
|
+
Из исходников, если стоит Go:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
go install github.com/tatnet-ru/tatnet-cli/cmd/tatnet@latest
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Начало работы
|
|
48
|
+
|
|
49
|
+
Ключ создаётся в панели: **Аккаунт → API-ключи**. Ключ принадлежит одному
|
|
50
|
+
аккаунту и несёт свою политику прав, поэтому аккаунт нигде не указывается.
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
tatnet auth login # спросит ключ, проверит его и сохранит
|
|
54
|
+
tatnet auth status # чей ключ и что он может
|
|
55
|
+
tatnet project list
|
|
56
|
+
tatnet profile set-project прод # проект по умолчанию
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Ключ проверяется до записи в конфиг: сохранённый нерабочий ключ выглядел бы
|
|
60
|
+
как настроенный CLI и падал бы на первой же команде.
|
|
61
|
+
|
|
62
|
+
## Примеры
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
tatnet vm list
|
|
66
|
+
tatnet vm get web-1 # по имени или hostname, не только по id
|
|
67
|
+
tatnet vm stop web-1
|
|
68
|
+
tatnet vm backup create web-1 --name до-обновления
|
|
69
|
+
|
|
70
|
+
tatnet app deploy магазин
|
|
71
|
+
tatnet app env set магазин DATABASE_URL 'postgres://…' --secret
|
|
72
|
+
tatnet app job run магазин миграции
|
|
73
|
+
tatnet app run list магазин --job миграции
|
|
74
|
+
|
|
75
|
+
tatnet pg list
|
|
76
|
+
tatnet pg parameters get основная # заданное рядом с применённым
|
|
77
|
+
tatnet pg ca основная --out ca.crt
|
|
78
|
+
tatnet pg backup list основная
|
|
79
|
+
|
|
80
|
+
tatnet dns record create example.com www A 185.152.80.60
|
|
81
|
+
tatnet s3 bucket create фото --public
|
|
82
|
+
tatnet s3 object presign фото отчёт.pdf
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Вывод
|
|
86
|
+
|
|
87
|
+
| `-o` | что делает |
|
|
88
|
+
|---|---|
|
|
89
|
+
| `table` | по умолчанию, только ключевые колонки |
|
|
90
|
+
| `wide` | плюс идентификаторы и подробности |
|
|
91
|
+
| `json` | ровно то, что вернул API — для скриптов |
|
|
92
|
+
| `yaml` | то же в YAML |
|
|
93
|
+
|
|
94
|
+
Списки вычитываются **целиком**: поле `count` в ответах API — размер
|
|
95
|
+
страницы, а не размер набора, поэтому конец определяется короткой
|
|
96
|
+
страницей. `--limit` ограничивает явно.
|
|
97
|
+
|
|
98
|
+
## Профили
|
|
99
|
+
|
|
100
|
+
Конфиг лежит в `~/.config/tatnet/config.yaml` (или `$TATNET_CONFIG`),
|
|
101
|
+
пишется режимом 0600 — в нём ключ.
|
|
102
|
+
|
|
103
|
+
```yaml
|
|
104
|
+
current: прод
|
|
105
|
+
profiles:
|
|
106
|
+
прод:
|
|
107
|
+
api_key: tn_live_…
|
|
108
|
+
project: 7f3c9c1e-…
|
|
109
|
+
стенд:
|
|
110
|
+
api_key: tn_live_…
|
|
111
|
+
base_url: https://api.stage.tatnet.ru/v1
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
tatnet profile list
|
|
116
|
+
tatnet profile use стенд
|
|
117
|
+
tatnet --profile стенд vm list
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Переменные окружения перебивают профиль, флаги — переменные:
|
|
121
|
+
`TATNET_API_KEY`, `TATNET_BASE_URL`, `TATNET_PROJECT`, `TATNET_PROFILE`,
|
|
122
|
+
`TATNET_OUTPUT`, `TATNET_CONFIG`.
|
|
123
|
+
|
|
124
|
+
## `tatnet api` — всё остальное
|
|
125
|
+
|
|
126
|
+
Своими командами выведены 91 операция из 161. Остальные — балансировщики,
|
|
127
|
+
сети, Kubernetes, функции, тома, домены, сертификаты — доступны прямым
|
|
128
|
+
вызовом:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
tatnet api --list load-balancers # что вообще есть
|
|
132
|
+
tatnet api /vpcs
|
|
133
|
+
tatnet api /floating-ips -X POST -f name=fip-1 -f cluster_id=…
|
|
134
|
+
tatnet api /projects/<id>/kubernetes-clusters/<id>/kubeconfig
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Адрес проверяется по вшитому контракту **до** отправки: иначе опечатка
|
|
138
|
+
вернула бы 404, неотличимый от «такого ресурса нет». Если API новее этого
|
|
139
|
+
CLI — `--allow-unknown`.
|
|
140
|
+
|
|
141
|
+
## Разрушающие действия
|
|
142
|
+
|
|
143
|
+
Удаление, сброс пароля и замена узлов спрашивают подтверждение. Когда ввод
|
|
144
|
+
не терминал (скрипт, CI), вопрос задать некому — такие команды **требуют
|
|
145
|
+
`--yes`**, а не соглашаются молча.
|
|
146
|
+
|
|
147
|
+
## Что здесь проверяется тестами
|
|
148
|
+
|
|
149
|
+
Контракт связан с деревом команд гейтом (`internal/cli/coverage_test.go`):
|
|
150
|
+
|
|
151
|
+
* каждая операция, объявленная командой, обязана существовать в контракте —
|
|
152
|
+
переименовали операцию в API, CLI падает на сборке, а не у клиента;
|
|
153
|
+
* покрытый раздел покрыт **целиком** — новая операция в нём валит тест, а не
|
|
154
|
+
остаётся тихо недоступной;
|
|
155
|
+
* отложенный раздел не покрыт **частично** — наполовину выведенный раздел
|
|
156
|
+
это список, которому уже нельзя верить;
|
|
157
|
+
* вшитый контракт совпадает с контрактом той версии `tatnet-go`, на которой
|
|
158
|
+
собран CLI.
|
|
159
|
+
|
|
160
|
+
Обновление контракта: `./scripts/sync-contract.sh`, затем `go test ./...` —
|
|
161
|
+
гейт покажет, что появилось нового.
|
|
162
|
+
|
|
163
|
+
## Разработка
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
go build ./...
|
|
167
|
+
go test ./...
|
|
168
|
+
go run ./cmd/tatnet --help
|
|
169
|
+
```
|
package/bin/tatnet.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
// Тонкая обёртка: находит бинарник своей платформы и отдаёт ему управление.
|
|
5
|
+
//
|
|
6
|
+
// Сам бинарник лежит в отдельном пакете на платформу, подключённом через
|
|
7
|
+
// optionalDependencies с полями os/cpu — npm ставит ровно один подходящий.
|
|
8
|
+
// Скачивания в postinstall здесь намеренно нет: он не работает при
|
|
9
|
+
// --ignore-scripts, требует сети в момент установки и ломает офлайн-кэш,
|
|
10
|
+
// а npx выполняется как раз в тех средах, где всё это встречается.
|
|
11
|
+
|
|
12
|
+
const { spawnSync } = require("node:child_process");
|
|
13
|
+
const fs = require("node:fs");
|
|
14
|
+
const path = require("node:path");
|
|
15
|
+
|
|
16
|
+
// Платформенные пакеты — в скоупе @tatnet: незанятые имена вида
|
|
17
|
+
// tatnet-cli-win32-arm64 реестр отвергает эвристикой антиспама, а имена
|
|
18
|
+
// внутри собственной организации под неё не попадают. Главный пакет
|
|
19
|
+
// остаётся неймспейсным (`npx tatnet`) — его имя коротко и проходит.
|
|
20
|
+
const PACKAGES = {
|
|
21
|
+
"darwin-arm64": "@tatnet/cli-darwin-arm64",
|
|
22
|
+
"darwin-x64": "@tatnet/cli-darwin-x64",
|
|
23
|
+
"linux-arm64": "@tatnet/cli-linux-arm64",
|
|
24
|
+
"linux-x64": "@tatnet/cli-linux-x64",
|
|
25
|
+
"win32-arm64": "@tatnet/cli-win32-arm64",
|
|
26
|
+
"win32-x64": "@tatnet/cli-win32-x64",
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const RELEASES = "https://github.com/tatnet-ru/tatnet-cli/releases";
|
|
30
|
+
|
|
31
|
+
function fail(message) {
|
|
32
|
+
process.stderr.write("tatnet: " + message + "\n");
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function resolveBinary() {
|
|
37
|
+
const key = process.platform + "-" + process.arch;
|
|
38
|
+
const pkg = PACKAGES[key];
|
|
39
|
+
if (!pkg) {
|
|
40
|
+
fail(
|
|
41
|
+
"нет сборки для " + key + ".\n" +
|
|
42
|
+
"Поддерживаются: " + Object.keys(PACKAGES).join(", ") + ".\n" +
|
|
43
|
+
"Соберите из исходников: go install github.com/tatnet-ru/tatnet-cli/cmd/tatnet@latest"
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const exe = process.platform === "win32" ? "tatnet.exe" : "tatnet";
|
|
48
|
+
let manifest;
|
|
49
|
+
try {
|
|
50
|
+
// Через package.json, а не напрямую по файлу: так путь находится
|
|
51
|
+
// одинаково и в обычном node_modules, и в pnpm со ссылками.
|
|
52
|
+
manifest = require.resolve(pkg + "/package.json");
|
|
53
|
+
} catch {
|
|
54
|
+
fail(
|
|
55
|
+
"пакет " + pkg + " не установлен.\n" +
|
|
56
|
+
"Так бывает при установке с --no-optional или --ignore-optional.\n" +
|
|
57
|
+
"Поставьте его явно: npm i " + pkg + "\n" +
|
|
58
|
+
"Либо возьмите бинарник: " + RELEASES
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const binary = path.join(path.dirname(manifest), "bin", exe);
|
|
63
|
+
if (!fs.existsSync(binary)) {
|
|
64
|
+
fail("пакет " + pkg + " установлен, но бинарника в нём нет: " + binary);
|
|
65
|
+
}
|
|
66
|
+
return binary;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function ensureExecutable(binary) {
|
|
70
|
+
if (process.platform === "win32") return;
|
|
71
|
+
try {
|
|
72
|
+
fs.accessSync(binary, fs.constants.X_OK);
|
|
73
|
+
} catch {
|
|
74
|
+
// Некоторые установщики теряют бит запуска при распаковке.
|
|
75
|
+
try {
|
|
76
|
+
fs.chmodSync(binary, 0o755);
|
|
77
|
+
} catch (err) {
|
|
78
|
+
fail("бинарник не исполняемый и права поправить не удалось: " + err.message);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const binary = resolveBinary();
|
|
84
|
+
ensureExecutable(binary);
|
|
85
|
+
|
|
86
|
+
const result = spawnSync(binary, process.argv.slice(2), { stdio: "inherit" });
|
|
87
|
+
|
|
88
|
+
if (result.error) {
|
|
89
|
+
fail("не удалось запустить " + binary + ": " + result.error.message);
|
|
90
|
+
}
|
|
91
|
+
// Код возврата обязан дойти до вызывающего: на CLI строят скрипты, и
|
|
92
|
+
// потерянный ненулевой код превратил бы отказ в успех.
|
|
93
|
+
if (result.signal) {
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
process.exit(result.status === null ? 1 : result.status);
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tatnet",
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"description": "Консольный клиент публичного API TatNet",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"tatnet",
|
|
7
|
+
"cli",
|
|
8
|
+
"cloud",
|
|
9
|
+
"postgres",
|
|
10
|
+
"valkey",
|
|
11
|
+
"dns",
|
|
12
|
+
"s3"
|
|
13
|
+
],
|
|
14
|
+
"homepage": "https://github.com/tatnet-ru/tatnet-cli#readme",
|
|
15
|
+
"bugs": "https://github.com/tatnet-ru/tatnet-cli/issues",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/tatnet-ru/tatnet-cli.git"
|
|
19
|
+
},
|
|
20
|
+
"bin": {
|
|
21
|
+
"tatnet": "bin/tatnet.js"
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"bin/tatnet.js",
|
|
25
|
+
"README.md"
|
|
26
|
+
],
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=18"
|
|
29
|
+
},
|
|
30
|
+
"optionalDependencies": {
|
|
31
|
+
"@tatnet/cli-darwin-arm64": "0.1.3",
|
|
32
|
+
"@tatnet/cli-darwin-x64": "0.1.3",
|
|
33
|
+
"@tatnet/cli-linux-arm64": "0.1.3",
|
|
34
|
+
"@tatnet/cli-linux-x64": "0.1.3",
|
|
35
|
+
"@tatnet/cli-win32-arm64": "0.1.3",
|
|
36
|
+
"@tatnet/cli-win32-x64": "0.1.3"
|
|
37
|
+
}
|
|
38
|
+
}
|