# regcloud-api Клиент к API облака REG.RU (Рег.облако), точка входа `https://api.cloudvps.reg.ru`. Полное покрытие API: серверы и все действия над ними, снимки, образы, тарифы, регионы, SSH-ключи, IP-адреса и обратные записи, приватные сети, kubeconfig кластеров, история операций и биллинг. ## Установка ```bash pip install git+https://git.stackworks.ru/viktor/regcloud-api.git ``` Токен берётся в личном кабинете, в разделе настроек, и кладётся в `REGRU_CLOUD_TOKEN`. ## Осмотреться ```python from regcloud_api import RegCloud api = RegCloud() for r in api.regions(): # где можно размещаться print(r["slug"], r["name"]) for i in api.distributions(): # операционные системы print(i["slug"], i["distribution"]) for i in api.applications(): # готовые сборки: панели, докер, гитлаб print(i["slug"]) for s in api.sizes(): # тарифы print(s["slug"], s["vcpus"], "ядер", s["price"], "р/час") ``` Во второй версии API образов заметно больше и они разложены по регионам. ```python for i in api.images_v2("openstack-spb1", type="distribution"): print(i["id"], i["name"]) ``` ## Тарифы Slug собирается по шаблону `c<ядра>-m<память>-d<диск>-<линейка>`. Клиент умеет собирать его сам и заодно проверять, что такое сочетание вообще существует. ```python from regcloud_api import build_size, parse_size RegCloud.make_size(4, 8, 120, "hp") # 'c4-m8-d120-hp' build_size(4, 5, 120, "hp") # ValueError, при 4 ядрах памяти 5 ГБ не бывает parse_size("c8-m32-d128-g1-a4000-gpu") # {'gpu': 'A4000 16 ГБ', 'vcpus': 8, 'memory_gb': 32, 'disk_gb': 128, 'price_hour': 37.8} ``` Линейки: `std` стандартный, `stdp` стандартный плюс, `hp` производительный, `hps` производительный ФЗ-152, `ddc` выделенный CPU, `high` высокочастотный. ## Жизненный цикл сервера ```python key = api.add_ssh_key("deploy", "~/.ssh/id_ed25519.pub") # можно путём к файлу srv = api.create_server( size="c2-m4-d60-hp", image="ubuntu-24-04-amd64", name=api.random_name(), # платформа умеет придумывать имена region="openstack-msk1", ssh_keys=[key["fingerprint"]], ) info = api.wait_active(srv["id"]) print("адрес:", RegCloud.ip_of(info)) ``` Действия над сервером. ```python api.stop(id); api.start(id); api.reboot(id) api.resize(id, "c4-m8-d120-hp") # сменить тариф api.rebuild(id, "debian-12-amd64") # переустановить систему api.reset_password(id) api.vnc_link(id) # консоль, когда по ssh уже не зайти api.set_backups(id, True) api.clone(id, "копия") ``` Снимки. ```python api.snapshot(id, "base", offline=True) # платформа сама остановит сервер snap = api.wait_snapshot("base") api.create_server(size="c2-m4-d60-hp", image=snap["id"], region="openstack-msk1") api.servers_from_snapshot(snap["id"]) # кто уже поднят из этого снимка api.delete_snapshot(snap["id"]) ``` Удаление. ```python api.destroy_server(id) # дождётся снятия блокировки ``` ## Адреса и сети ```python api.ips(server_id) api.add_ip(server_id, ipv4=1) api.set_ptr("1.2.3.4", "mail.example.com") api.delete_ip("1.2.3.4") vpc = api.create_vpc("backoffice", region="openstack-msk1") api.vpc_attach(vpc["id"], server_id) api.vpc_members(vpc["id"]) api.vpc_detach(vpc["id"], server_id) ``` ## Деньги ```python api.money_left() # сколько на счету api.burn_rate() # сколько капает в час, в сутки и в месяц api.billing_history() api.history(limit=50) # что и когда делали с ресурсами api.prices() ``` ## Ошибки Все ошибки платформы разложены по смыслу, чтобы ловить прицельно. ```python from regcloud_api import NotFound, Locked, ValidationError, InsufficientFunds try: api.destroy_server(123) except NotFound: pass # его уже нет, и хорошо except Locked: pass # занят другой операцией ``` ## Особенности платформы, обойдённые внутри Собрано на живых серверах, чтобы вы на это не наступали. **Адрес сервера лежит в поле `ip`.** Поле `networks` из документации всегда пустое. `RegCloud.ip_of()` смотрит в оба места. **Снимок снимается только с работающего сервера.** У остановленного платформа отвечает `SERVER_IS_STOPPED`, останавливать его должна она сама по параметру `offline`. **После снимка сервер сидит в `locked`** и на удаление отвечает `RESOURCE_DELETE_ERROR`. Отпускает примерно через полминуты, поэтому `destroy_server()` повторяет попытки. Забытый сервер продолжает тарифицироваться, молча сдаваться тут нельзя. **`sizes()` возвращает не все линейки.** Тарифы с видеокартами в выдачу не попадают, хотя создание с ними работает. Их список лежит в `gpu_sizes()` и в [docs_slugs.md](docs_slugs.md). **Тарификация идёт от часа.** Двадцать минут работы списываются как полный час. ## Рядом - [docs_slugs.md](docs_slugs.md) — тарифы, образы, регионы, правила составления slug'ов - [openapi_v1.json](openapi_v1.json) — спецификация API, снятая с сервера платформы - [examples/](examples/) — примеры