feat: full ISPConfig remote API coverage + re-runnable generator (v0.2)
v0.1 shipped ~15 hand-audited methods across sites/dns/mail/databases/clients. That's enough for daily ops but every new Tort Host / cWHO feature has been hitting the wall at the edge of that coverage. This extends the SDK to wrap every method the panel exposes — 312 of them as of Rackham 2026-04-22, verified against the live list_functions() introspection call with only one name-mismatch (``__construct``, a PHP lifecycle artifact, not a real API method). The hand-audited helpers stay where they are. Every module now has two clearly-delimited sections: an auto-generated block at the top (emitted by tools/gen_methods.py from tools/method_inventory.json), and a HAND-EDIT ONLY BELOW block at the bottom that survives regeneration. Name collisions between auto and hand always resolve in favor of the hand version — the generator emits a ``# skipped foo: hand-audited helper takes precedence`` comment in the auto block for traceability. Pipeline: - tools/extract_inventory.py reads remote.*.inc.php + remoting.inc.php, pulls docblocks + param defaults, dumps one JSON record per method. Regex is balanced-paren aware so ``$params = array()`` defaults don't truncate the signature at the wrong close-paren (that footgun hid three methods from the first run — sites_aps_available_packages_list, sites_aps_instance_delete, openvz_vm_add_from_template). - tools/method_inventory.json is the committed inventory — future ISPConfig upgrades diff against this file to see scope at a glance. - tools/gen_methods.py groups by method-name prefix onto the module classes listed in the README table, emits a 1:1 Python wrapper per method with the original PHP filename + line number in the docstring, and ensures ``from typing import Any`` is present in preexisting modules before emitting ``Any`` type annotations. New submodules (all auto-generated, wired into ISPConfigClient.__init__): admin, aps, backups, cron, domains, ftp, misc, monitor, openvz, server, shell, webdav. Existing modules (sites, dns, mail, databases, clients) got their auto block filled in and their hand-audited helpers preserved. Escape hatches on the top-level client: - raw_call(method, *args) routes an arbitrary method name through the same session-management + retry + fault-mapping pipeline the typed wrappers use. Fix for "panel shipped a new method, SDK hasn't caught up" — callers don't have to reach back into _soap. - list_functions() wraps get_function_list() for panel introspection. Fault mapping widened: ``no_client_found`` and "no user account" messages now map to NotFoundError instead of FaultError, matching the existing ``no_domain_found`` convention. Older code that caught raw FaultError there will still work (NotFoundError extends ISPConfigError) but callers can now catch the specific type. Testing: - tests/test_unit.py — 12 existing pure-unit tests pass unchanged. - tests/test_smoke.py — extended from 4 read-only calls to 21. One probe per new auto-generated module plus raw_call and list_functions smoke tests. Methods gated behind admin permission skip gracefully with a documented reason (kayos is a reseller, not admin): monitor_jobqueue_count, sites_cron_get, sites_ftp_user_get, openvz_get_free_ip, quota_get_by_user. Results against Rackham 2026-04-22: 28 passed, 5 skipped (all documented admin-only), 0 failed. - ISPCONFIG_TEST_VERIFY_SSL=0 env-var knob added to conftest for panels with self-signed or mismatched certs. Version bump 0.1.0 -> 0.2.0. README restructured into Hand-audited / Auto-generated / Escape hatch / Footguns sections with a regeneration recipe for future ISPConfig upgrades. Ruff per-file SLF001 ignore extended to every submodule (submodules are all authorized callers of the client's private ``_call`` dispatcher by design). mypy strict passes; ruff check passes; ruff format applied across src / tools / tests.
This commit is contained in:
parent
9438b4e751
commit
44ce76cb44
28 changed files with 14173 additions and 184 deletions
186
README.md
186
README.md
|
|
@ -4,8 +4,10 @@ Python SDK for the ISPConfig remote SOAP API. Internal tooling for the Sulkta
|
||||||
Coop — wraps the panel's SOAP surface so we stop writing throw-away PHP
|
Coop — wraps the panel's SOAP surface so we stop writing throw-away PHP
|
||||||
scripts every time we need to touch a site, zone, or mailbox.
|
scripts every time we need to touch a site, zone, or mailbox.
|
||||||
|
|
||||||
The SDK covers the methods we actually use today (sites, DNS, mail, databases,
|
v0.2 covers the **full remote API** — every method exposed by ISPConfig's
|
||||||
clients). More methods can be added as needed.
|
`remote/index.php`, 312 of them as of Rackham 2026-04-22. The hand-audited
|
||||||
|
helpers (stable names, param-order fixes, convenience wrappers) sit on top
|
||||||
|
of auto-generated wrappers that mirror the PHP surface 1:1.
|
||||||
|
|
||||||
## Why no zeep?
|
## Why no zeep?
|
||||||
|
|
||||||
|
|
@ -45,9 +47,35 @@ managed internally — callers don't touch them.
|
||||||
|
|
||||||
Set `verify_ssl=False` for dev boxes with self-signed certs. Default is `True`.
|
Set `verify_ssl=False` for dev boxes with self-signed certs. Default is `True`.
|
||||||
|
|
||||||
## Modules at a glance
|
## Changelog
|
||||||
|
|
||||||
### `sites`
|
### 0.2.0 — 2026-04-22
|
||||||
|
|
||||||
|
Full-coverage extension. Every remote method ISPConfig exposes is now wrapped
|
||||||
|
in one of the submodules below. Hand-audited helpers from v0.1 (footgun
|
||||||
|
fixes, convenience wrappers) are preserved beneath a delimiter and survive
|
||||||
|
regeneration. New submodules: `admin`, `aps`, `backups`, `cron`, `domains`,
|
||||||
|
`ftp`, `misc`, `monitor`, `openvz`, `server`, `shell`, `webdav`.
|
||||||
|
|
||||||
|
- Code generator at `tools/gen_methods.py` driven by `tools/method_inventory.json`.
|
||||||
|
- One-command refresh for future ISPConfig upgrades (see below).
|
||||||
|
- `ISPConfigClient.raw_call(method, *args)` escape hatch for methods not yet
|
||||||
|
in the inventory.
|
||||||
|
- `ISPConfigClient.list_functions()` introspects the panel's exposed method list.
|
||||||
|
- Live smoke test extended from 4 to 21 read-only calls covering every module.
|
||||||
|
|
||||||
|
### 0.1.0 — 2026-04-21
|
||||||
|
|
||||||
|
Initial release. Hand-audited coverage of sites / dns / mail / databases / clients.
|
||||||
|
|
||||||
|
## Modules
|
||||||
|
|
||||||
|
### Hand-audited (stable API, verified in prod)
|
||||||
|
|
||||||
|
Names normalized for ergonomics; footgun fixes and retries baked in. These
|
||||||
|
are the wrappers you should prefer.
|
||||||
|
|
||||||
|
#### `sites`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
c.sites.web_domain_get(156)
|
c.sites.web_domain_get(156)
|
||||||
|
|
@ -56,38 +84,94 @@ c.sites.enable_php(156, mode="php-fpm", server_php_id=2, pm="ondemand")
|
||||||
c.sites.enable_letsencrypt(156)
|
c.sites.enable_letsencrypt(156)
|
||||||
```
|
```
|
||||||
|
|
||||||
### `dns`
|
#### `dns`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
zone_id = c.dns.zone_get_id("example.com.") # note the trailing dot
|
zone_id = c.dns.zone_get_id("example.com") # trailing dot is stripped either way
|
||||||
zone = c.dns.zone_get(zone_id)
|
zone = c.dns.zone_get(zone_id)
|
||||||
records = c.dns.rr_get_all_by_zone(zone_id)
|
records = c.dns.rr_get_all_by_zone(zone_id)
|
||||||
rr_id = c.dns.a_add(0, {"zone": zone_id, "name": "www", "data": "1.2.3.4", "ttl": 3600, "active": "Y"})
|
rr_id = c.dns.a_add(0, {"zone": zone_id, "name": "www", "data": "1.2.3.4", "ttl": 3600, "active": "Y"})
|
||||||
```
|
```
|
||||||
|
|
||||||
### `mail`
|
#### `mail`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
md = c.mail.domain_get_by_domain("example.com")
|
md = c.mail.domain_get_by_domain("example.com")
|
||||||
users = c.mail.user_get({"email": "%@example.com"})
|
users = c.mail.user_get({"email": "%@example.com"}) # always a list
|
||||||
new_id = c.mail.create_mailbox(client_id=5, domain="example.com",
|
new_id = c.mail.create_mailbox(client_id=5, domain="example.com",
|
||||||
local_part="info", password="x", quota_mb=2048)
|
local_part="info", password="x", quota_mb=2048)
|
||||||
```
|
```
|
||||||
|
|
||||||
### `databases`
|
#### `databases`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
db = c.databases.get(42)
|
db = c.databases.get(42)
|
||||||
c.databases.user_update(client_id=5, primary_id=42, params={"database_password": "x"})
|
c.databases.user_update(client_id=5, primary_id=42, params={"database_password": "x"})
|
||||||
```
|
```
|
||||||
|
|
||||||
### `clients`
|
#### `clients`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
cli = c.clients.get_by_username("jacob")
|
cli = c.clients.get_by_username("jacob")
|
||||||
groupid = c.clients.get_groupid(cli["client_id"])
|
groupid = c.clients.get_groupid(cli["client_id"])
|
||||||
|
ids = c.clients.get_all()
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Auto-generated (full surface, v0.2)
|
||||||
|
|
||||||
|
Wrappers mirror the PHP method names 1:1. Param shapes come from PHPDoc where
|
||||||
|
available and default to `Any` otherwise. Verified to wire up against Rackham
|
||||||
|
2026-04-22 but not yet battle-tested in production use — file issues if you
|
||||||
|
hit one.
|
||||||
|
|
||||||
|
| Module | Class | Methods |
|
||||||
|
|--------------|----------------------|---------|
|
||||||
|
| `admin` | `AdminModule` | 10 |
|
||||||
|
| `aps` | `ApsModule` | 10 |
|
||||||
|
| `backups` | `BackupsModule` | 2 |
|
||||||
|
| `clients` | `ClientsModule` | 19 |
|
||||||
|
| `cron` | `CronModule` | 4 |
|
||||||
|
| `databases` | `DatabasesModule` | 9 |
|
||||||
|
| `dns` | `DnsModule` | 87 |
|
||||||
|
| `domains` | `DomainsModule` | 5 |
|
||||||
|
| `ftp` | `FtpModule` | 5 |
|
||||||
|
| `mail` | `MailModule` | 82 |
|
||||||
|
| `misc` | `MiscModule` | 4 |
|
||||||
|
| `monitor` | `MonitorModule` | 1 |
|
||||||
|
| `openvz` | `OpenvzModule` | 22 |
|
||||||
|
| `server` | `ServerModule` | 12 |
|
||||||
|
| `shell` | `ShellModule` | 4 |
|
||||||
|
| `sites` | `SitesModule` | 29 |
|
||||||
|
| `webdav` | `WebdavModule` | 4 |
|
||||||
|
|
||||||
|
Every auto-generated method carries a docstring with the original PHP
|
||||||
|
filename + line number and an `AUTO-GENERATED — param shapes may need
|
||||||
|
verification` warning. Methods that exist in both the auto and hand-audited
|
||||||
|
blocks are skipped in the auto block — the hand version wins.
|
||||||
|
|
||||||
|
### Escape hatch
|
||||||
|
|
||||||
|
For methods not yet in the inventory (e.g. on a newer ISPConfig version than
|
||||||
|
we've regenerated against):
|
||||||
|
|
||||||
|
```python
|
||||||
|
result = c.raw_call("some_new_method", arg1, arg2)
|
||||||
|
```
|
||||||
|
|
||||||
|
`raw_call` routes through the same session-management + fault-mapping
|
||||||
|
pipeline as typed methods, so auth/retry still works. To see what the panel
|
||||||
|
exposes:
|
||||||
|
|
||||||
|
```python
|
||||||
|
funcs = c.list_functions()
|
||||||
|
```
|
||||||
|
|
||||||
|
### Not covered
|
||||||
|
|
||||||
|
- `__construct` — PHP constructor, not a real API method.
|
||||||
|
- Anything gated by ISPConfig plugins we don't have installed — probing via
|
||||||
|
`raw_call` will return a faultstring like "Method not found".
|
||||||
|
|
||||||
## Footguns (captured here so nobody has to rediscover them)
|
## Footguns (captured here so nobody has to rediscover them)
|
||||||
|
|
||||||
- **`sites_web_domain_update`'s second arg is `client_id`, not `primary_id`.**
|
- **`sites_web_domain_update`'s second arg is `client_id`, not `primary_id`.**
|
||||||
|
|
@ -112,9 +196,9 @@ groupid = c.clients.get_groupid(cli["client_id"])
|
||||||
- **`mail_user_get` with a filter dict returns inconsistent shapes.** If the
|
- **`mail_user_get` with a filter dict returns inconsistent shapes.** If the
|
||||||
filter matches multiple rows you get an array; exactly-one match returns a
|
filter matches multiple rows you get an array; exactly-one match returns a
|
||||||
bare map. Our `mail.user_get(filter_dict)` always normalizes to a list.
|
bare map. Our `mail.user_get(filter_dict)` always normalizes to a list.
|
||||||
- **`no_domain_found` fault.** Both `dns_zone_get_id` and (in some paths)
|
- **`no_domain_found` / `no_client_found` faults.** These are typed as
|
||||||
`mail_domain_get_by_domain` return a SOAP fault with `faultcode=no_domain_found`
|
`NotFoundError`; `client_get_by_username("nope")` raises it. Older code
|
||||||
when the record is missing. Mapped to `NotFoundError`.
|
may have caught raw `FaultError` — v0.2 reclassifies both.
|
||||||
- **`dns_a_add` type-column bug.** On some ISPConfig versions (<= ~3.2.11)
|
- **`dns_a_add` type-column bug.** On some ISPConfig versions (<= ~3.2.11)
|
||||||
`dns_a_add` inserts the `dns_rr` row without setting the `type` column,
|
`dns_a_add` inserts the `dns_rr` row without setting the `type` column,
|
||||||
so BIND never emits the record. `DnsModule.a_add(..., fix_type_bug=True)`
|
so BIND never emits the record. `DnsModule.a_add(..., fix_type_bug=True)`
|
||||||
|
|
@ -130,6 +214,17 @@ groupid = c.clients.get_groupid(cli["client_id"])
|
||||||
- **Filter dicts on `mail_user_get`.** Pass an int to get one row; pass a
|
- **Filter dicts on `mail_user_get`.** Pass an int to get one row; pass a
|
||||||
dict like `{"email": "%@example.com"}` to get a list. The SOAP method is
|
dict like `{"email": "%@example.com"}` to get a list. The SOAP method is
|
||||||
overloaded and untyped on the wire.
|
overloaded and untyped on the wire.
|
||||||
|
- **PHP method signatures with `array()` defaults.** ISPConfig's extract
|
||||||
|
regex used to stop at the first `)` in `$params = array()`, missing three
|
||||||
|
methods on 3.2.x (`sites_aps_available_packages_list`,
|
||||||
|
`sites_aps_instance_delete`, `openvz_vm_add_from_template`). Fixed in
|
||||||
|
`tools/extract_inventory.py` with balanced-paren matching — worth
|
||||||
|
double-checking on future panel upgrades.
|
||||||
|
- **Known admin-only methods.** Reseller logins fault with "permission denied"
|
||||||
|
on a non-admin user. These are skipped in the smoke tests:
|
||||||
|
`monitor_jobqueue_count`, `sites_cron_get`, `sites_ftp_user_get`,
|
||||||
|
`openvz_*`, `quota_get_by_user`, `client_templates_get_all`. Use an admin
|
||||||
|
login if you need them.
|
||||||
|
|
||||||
## Errors
|
## Errors
|
||||||
|
|
||||||
|
|
@ -147,7 +242,7 @@ ISPConfigError
|
||||||
## Tests
|
## Tests
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pytest # unit tests only, no network
|
pytest # unit tests only, no network (12 tests)
|
||||||
```
|
```
|
||||||
|
|
||||||
To run the live smoke test against a real panel:
|
To run the live smoke test against a real panel:
|
||||||
|
|
@ -156,11 +251,47 @@ To run the live smoke test against a real panel:
|
||||||
export ISPCONFIG_TEST_URL="https://panel.example.com:8080/remote/index.php"
|
export ISPCONFIG_TEST_URL="https://panel.example.com:8080/remote/index.php"
|
||||||
export ISPCONFIG_TEST_USER="kayos"
|
export ISPCONFIG_TEST_USER="kayos"
|
||||||
export ISPCONFIG_TEST_PASS="..."
|
export ISPCONFIG_TEST_PASS="..."
|
||||||
|
export ISPCONFIG_TEST_VERIFY_SSL=0 # for self-signed certs
|
||||||
pytest tests/test_smoke.py
|
pytest tests/test_smoke.py
|
||||||
```
|
```
|
||||||
|
|
||||||
The smoke test is read-only — no `_add` / `_update` / `_delete` calls. Safe
|
21 read-only calls covering every auto-generated module + the originals. No
|
||||||
against production.
|
`_add` / `_update` / `_delete` calls — safe against production. Methods that
|
||||||
|
require admin privileges skip gracefully with a documented reason.
|
||||||
|
|
||||||
|
## Regenerating for newer ISPConfig versions
|
||||||
|
|
||||||
|
When ISPConfig ships a new version on Rackham (or another panel), resync:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Pull fresh PHP sources from the panel (sudo required; ask Cobb for creds):
|
||||||
|
mkdir -p /tmp/ispconfig-php-src
|
||||||
|
ssh rackham "sudo tar -cz -C /usr/local/ispconfig/interface/lib/classes/remote.d ." \
|
||||||
|
| tar -xz -C /tmp/ispconfig-php-src/
|
||||||
|
ssh rackham "sudo cat /usr/local/ispconfig/interface/lib/classes/remoting.inc.php" \
|
||||||
|
> /tmp/ispconfig-php-src/remoting.inc.php
|
||||||
|
|
||||||
|
# 2. Re-extract the method inventory:
|
||||||
|
python3 tools/extract_inventory.py /tmp/ispconfig-php-src tools/method_inventory.json
|
||||||
|
|
||||||
|
# 3. Regenerate wrappers:
|
||||||
|
python3 tools/gen_methods.py
|
||||||
|
|
||||||
|
# 4. Clean up formatting + sanity check:
|
||||||
|
ruff format src/ tools/
|
||||||
|
ruff check src/ tools/
|
||||||
|
mypy src/ispconfig
|
||||||
|
pytest
|
||||||
|
|
||||||
|
# 5. Review and commit:
|
||||||
|
git diff --stat
|
||||||
|
git diff tools/method_inventory.json # new methods jump out here
|
||||||
|
```
|
||||||
|
|
||||||
|
Hand-edits below the `HAND-EDIT ONLY BELOW` marker in each module survive
|
||||||
|
regeneration. Method-name collisions between auto and hand are resolved in
|
||||||
|
favor of the hand version; the generator emits a `# skipped ...` comment
|
||||||
|
in the auto block for traceability.
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
|
|
@ -171,29 +302,6 @@ mypy src/ispconfig
|
||||||
pytest
|
pytest
|
||||||
```
|
```
|
||||||
|
|
||||||
## Not yet covered
|
|
||||||
|
|
||||||
The remote API surface is huge. These are intentionally left out of v0.1 —
|
|
||||||
add as needed:
|
|
||||||
|
|
||||||
- `sites_web_aliasdomain_*`, `sites_web_subdomain_*`,
|
|
||||||
`sites_web_vhost_{subdomain,aliasdomain}_*`
|
|
||||||
- `sites_ftp_user_*`, `sites_shell_user_*`, `sites_webdav_user_*`
|
|
||||||
- `sites_cron_*`
|
|
||||||
- `sites_web_domain_backup`, `sites_web_domain_backup_list`,
|
|
||||||
`mail_user_backup`, `mail_user_backup_list`
|
|
||||||
- `dns_{aaaa,ns,srv,ptr,tlsa,ds,caa,sshfp,dname,loc,hinfo,naptr,rp,alias}_*`
|
|
||||||
- `dns_slave_*`, `dns_zone_set_dnssec`, `dns_zone_get_by_user`, `dns_templatezone_*`
|
|
||||||
- `mail_alias_*`, `mail_aliasdomain_*`, `mail_catchall_*`, `mail_filter_*`,
|
|
||||||
`mail_fetchmail_*`, `mail_mailinglist_*`, `mail_policy_*`,
|
|
||||||
`mail_relay_{domain,recipient}_*`, `mail_transport_*`,
|
|
||||||
`mail_{whitelist,blacklist}_*`, `mail_spamfilter_*`, `mail_user_filter_*`
|
|
||||||
- `client_add`, `client_update`, `client_delete`, `client_change_password`,
|
|
||||||
`client_template_additional_*`, `client_templates_get_all`,
|
|
||||||
`client_login_get`
|
|
||||||
- `server_get`, `server_get_all`, `admin.*`, `monitor.*`, `aps.*`,
|
|
||||||
`openvz.*`, `domains.*`
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
MIT — see `LICENSE`.
|
MIT — see `LICENSE`.
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "ispconfig"
|
name = "ispconfig"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
description = "Python SDK for the ISPConfig remote SOAP API — Sulkta Coop internal tooling."
|
description = "Python SDK for the ISPConfig remote SOAP API — Sulkta Coop internal tooling."
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
license = { text = "MIT" }
|
license = { text = "MIT" }
|
||||||
|
|
@ -83,10 +83,24 @@ ignore = [
|
||||||
"tests/*" = ["SLF001", "N802"]
|
"tests/*" = ["SLF001", "N802"]
|
||||||
# Submodules call back into the client's dispatcher (`_call`) by design —
|
# Submodules call back into the client's dispatcher (`_call`) by design —
|
||||||
# it's the single chokepoint for session management and retry logic.
|
# it's the single chokepoint for session management and retry logic.
|
||||||
"src/ispconfig/sites.py" = ["SLF001"]
|
# Every submodule needs this waiver; generator output follows the same pattern.
|
||||||
"src/ispconfig/dns.py" = ["SLF001"]
|
"src/ispconfig/admin.py" = ["SLF001"]
|
||||||
"src/ispconfig/mail.py" = ["SLF001"]
|
"src/ispconfig/aps.py" = ["SLF001"]
|
||||||
|
"src/ispconfig/backups.py" = ["SLF001"]
|
||||||
"src/ispconfig/clients.py" = ["SLF001"]
|
"src/ispconfig/clients.py" = ["SLF001"]
|
||||||
|
"src/ispconfig/cron.py" = ["SLF001"]
|
||||||
|
"src/ispconfig/databases.py" = ["SLF001"]
|
||||||
|
"src/ispconfig/dns.py" = ["SLF001"]
|
||||||
|
"src/ispconfig/domains.py" = ["SLF001"]
|
||||||
|
"src/ispconfig/ftp.py" = ["SLF001"]
|
||||||
|
"src/ispconfig/mail.py" = ["SLF001"]
|
||||||
|
"src/ispconfig/misc.py" = ["SLF001"]
|
||||||
|
"src/ispconfig/monitor.py" = ["SLF001"]
|
||||||
|
"src/ispconfig/openvz.py" = ["SLF001"]
|
||||||
|
"src/ispconfig/server.py" = ["SLF001"]
|
||||||
|
"src/ispconfig/shell.py" = ["SLF001"]
|
||||||
|
"src/ispconfig/sites.py" = ["SLF001"]
|
||||||
|
"src/ispconfig/webdav.py" = ["SLF001"]
|
||||||
|
|
||||||
# ---- pytest ---------------------------------------------------------
|
# ---- pytest ---------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -95,14 +95,14 @@ class SoapTransport:
|
||||||
arg_xml = "".join(_encode_arg(name, value) for name, value in args)
|
arg_xml = "".join(_encode_arg(name, value) for name, value in args)
|
||||||
return (
|
return (
|
||||||
'<?xml version="1.0" encoding="UTF-8"?>'
|
'<?xml version="1.0" encoding="UTF-8"?>'
|
||||||
'<SOAP-ENV:Envelope'
|
"<SOAP-ENV:Envelope"
|
||||||
' xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"'
|
' xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"'
|
||||||
' xmlns:ns1="urn:ispconfig"'
|
' xmlns:ns1="urn:ispconfig"'
|
||||||
' xmlns:xsd="http://www.w3.org/2001/XMLSchema"'
|
' xmlns:xsd="http://www.w3.org/2001/XMLSchema"'
|
||||||
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
|
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
|
||||||
' xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">'
|
' xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">'
|
||||||
f'<SOAP-ENV:Body><ns1:{method}>{arg_xml}</ns1:{method}></SOAP-ENV:Body>'
|
f"<SOAP-ENV:Body><ns1:{method}>{arg_xml}</ns1:{method}></SOAP-ENV:Body>"
|
||||||
'</SOAP-ENV:Envelope>'
|
"</SOAP-ENV:Envelope>"
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
@ -148,7 +148,7 @@ def _encode_arg(name: str, value: Any) -> str:
|
||||||
if isinstance(value, Mapping):
|
if isinstance(value, Mapping):
|
||||||
items = "".join(
|
items = "".join(
|
||||||
f'<item><key xsi:type="xsd:string">{xml_escape(str(k))}</key>'
|
f'<item><key xsi:type="xsd:string">{xml_escape(str(k))}</key>'
|
||||||
f'{_encode_value_tag("value", v)}</item>'
|
f"{_encode_value_tag('value', v)}</item>"
|
||||||
for k, v in value.items()
|
for k, v in value.items()
|
||||||
)
|
)
|
||||||
return f'<{name} xsi:type="ns2:Map" xmlns:ns2="http://xml.apache.org/xml-soap">{items}</{name}>'
|
return f'<{name} xsi:type="ns2:Map" xmlns:ns2="http://xml.apache.org/xml-soap">{items}</{name}>'
|
||||||
|
|
@ -223,10 +223,7 @@ def _is_map(el: ET.Element) -> bool:
|
||||||
return False
|
return False
|
||||||
if not all(_local(k.tag) == "item" for k in kids):
|
if not all(_local(k.tag) == "item" for k in kids):
|
||||||
return False
|
return False
|
||||||
return any(
|
return any(any(_local(gk.tag) == "key" for gk in item) for item in kids)
|
||||||
any(_local(gk.tag) == "key" for gk in item)
|
|
||||||
for item in kids
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _is_array(el: ET.Element) -> bool:
|
def _is_array(el: ET.Element) -> bool:
|
||||||
|
|
|
||||||
177
src/ispconfig/admin.py
Normal file
177
src/ispconfig/admin.py
Normal file
|
|
@ -0,0 +1,177 @@
|
||||||
|
"""``admin.*`` — auto-generated ISPConfig remote-API wrappers.
|
||||||
|
|
||||||
|
This module is produced by ``tools/gen_methods.py`` from the
|
||||||
|
``tools/method_inventory.json`` catalog. Hand-edits go below the
|
||||||
|
``---- HAND-EDIT ONLY BELOW ----`` marker — they survive regeneration.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .client import ISPConfigClient
|
||||||
|
|
||||||
|
|
||||||
|
class AdminModule:
|
||||||
|
"""Auto-generated module: Admin.
|
||||||
|
|
||||||
|
All methods below the ``AUTO-GENERATED START`` marker are produced
|
||||||
|
by ``tools/gen_methods.py``. Do not hand-edit that block — changes
|
||||||
|
will be overwritten on the next regeneration. Add helpers and
|
||||||
|
overrides below the ``HAND-EDIT ONLY BELOW`` marker instead.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, client: ISPConfigClient) -> None:
|
||||||
|
self._c = client
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED START (do not hand-edit above this line) ----
|
||||||
|
# Regenerate with: python3 tools/gen_methods.py
|
||||||
|
|
||||||
|
def config_value_add(self, group: Any, name: Any, value: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``config_value_add``.
|
||||||
|
|
||||||
|
Source: ``admin.inc.php`` line 181.
|
||||||
|
PHP signature: ``config_value_add($session_id, $group, $name, $value)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("config_value_add", ("group", group), ("name", name), ("value", value))
|
||||||
|
|
||||||
|
def config_value_delete(self, group: Any, name: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``config_value_delete``.
|
||||||
|
|
||||||
|
Source: ``admin.inc.php`` line 252.
|
||||||
|
PHP signature: ``config_value_delete($session_id, $group, $name)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("config_value_delete", ("group", group), ("name", name))
|
||||||
|
|
||||||
|
def config_value_get(self, group: Any, name: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``config_value_get``.
|
||||||
|
|
||||||
|
Source: ``admin.inc.php`` line 162.
|
||||||
|
PHP signature: ``config_value_get($session_id, $group, $name)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("config_value_get", ("group", group), ("name", name))
|
||||||
|
|
||||||
|
def config_value_replace(self, group: Any, name: Any, value: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``config_value_replace``.
|
||||||
|
|
||||||
|
Source: ``admin.inc.php`` line 229.
|
||||||
|
PHP signature: ``config_value_replace($session_id, $group, $name, $value)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("config_value_replace", ("group", group), ("name", name), ("value", value))
|
||||||
|
|
||||||
|
def config_value_update(self, group: Any, name: Any, value: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``config_value_update``.
|
||||||
|
|
||||||
|
Source: ``admin.inc.php`` line 205.
|
||||||
|
PHP signature: ``config_value_update($session_id, $group, $name, $value)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("config_value_update", ("group", group), ("name", name), ("value", value))
|
||||||
|
|
||||||
|
def sys_datalog_get(self, datalog_id: Any, newer: Any = False) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sys_datalog_get``.
|
||||||
|
|
||||||
|
Source: ``admin.inc.php`` line 294.
|
||||||
|
PHP signature: ``sys_datalog_get($session_id, $datalog_id, $newer = false)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sys_datalog_get", ("datalog_id", datalog_id), ("newer", newer))
|
||||||
|
|
||||||
|
def sys_datalog_get_by_tstamp(self, tstamp: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sys_datalog_get_by_tstamp``.
|
||||||
|
|
||||||
|
Source: ``admin.inc.php`` line 276.
|
||||||
|
PHP signature: ``sys_datalog_get_by_tstamp($session_id, $tstamp)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sys_datalog_get_by_tstamp", ("tstamp", tstamp))
|
||||||
|
|
||||||
|
def system_config_get(self, section: str, key: str | None = None) -> Any:
|
||||||
|
"""
|
||||||
|
Get the values of the system configuration
|
||||||
|
|
||||||
|
Source: ``admin.inc.php`` line 137.
|
||||||
|
PHP signature: ``system_config_get($session_id, $section, $key = null)``.
|
||||||
|
|
||||||
|
Params (from PHPDoc):
|
||||||
|
session (int): id
|
||||||
|
section (string): of the config field in the table. Could be 'web', 'dns', 'mail', 'dns', 'cron', etc
|
||||||
|
key (string|null): of the option that you want to get
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("system_config_get", ("section", section), ("key", key))
|
||||||
|
|
||||||
|
def system_config_set(self, section: str, key: str, value: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Set a value in the system configuration
|
||||||
|
|
||||||
|
Source: ``admin.inc.php`` line 113.
|
||||||
|
PHP signature: ``system_config_set($session_id, $section, $key, $value)``.
|
||||||
|
|
||||||
|
Params (from PHPDoc):
|
||||||
|
session (int): id
|
||||||
|
section (string): of the config field in the table. Could be 'web', 'dns', 'mail', 'dns', 'cron', etc
|
||||||
|
key (string): of the option that you want to set
|
||||||
|
option (string): value that you want to set
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("system_config_set", ("section", section), ("key", key), ("value", value))
|
||||||
|
|
||||||
|
def update_record_permissions(
|
||||||
|
self, tablename: Any, index_field: str, index_value: str, permissions: dict[str, Any] | list[Any]
|
||||||
|
) -> Any:
|
||||||
|
"""
|
||||||
|
set record permissions in any table
|
||||||
|
|
||||||
|
Source: ``admin.inc.php`` line 51.
|
||||||
|
PHP signature: ``update_record_permissions($session_id, $tablename, $index_field, $index_value, $permissions)``.
|
||||||
|
|
||||||
|
Params (from PHPDoc):
|
||||||
|
index_field (string)
|
||||||
|
index_value (string)
|
||||||
|
permissions (array)
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"update_record_permissions",
|
||||||
|
("tablename", tablename),
|
||||||
|
("index_field", index_field),
|
||||||
|
("index_value", index_value),
|
||||||
|
("permissions", permissions),
|
||||||
|
)
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED END ----
|
||||||
|
|
||||||
|
# ---- HAND-EDIT ONLY BELOW ----
|
||||||
154
src/ispconfig/aps.py
Normal file
154
src/ispconfig/aps.py
Normal file
|
|
@ -0,0 +1,154 @@
|
||||||
|
"""``aps.*`` — auto-generated ISPConfig remote-API wrappers.
|
||||||
|
|
||||||
|
This module is produced by ``tools/gen_methods.py`` from the
|
||||||
|
``tools/method_inventory.json`` catalog. Hand-edits go below the
|
||||||
|
``---- HAND-EDIT ONLY BELOW ----`` marker — they survive regeneration.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .client import ISPConfigClient
|
||||||
|
|
||||||
|
|
||||||
|
class ApsModule:
|
||||||
|
"""Auto-generated module: Aps.
|
||||||
|
|
||||||
|
All methods below the ``AUTO-GENERATED START`` marker are produced
|
||||||
|
by ``tools/gen_methods.py``. Do not hand-edit that block — changes
|
||||||
|
will be overwritten on the next regeneration. Add helpers and
|
||||||
|
overrides below the ``HAND-EDIT ONLY BELOW`` marker instead.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, client: ISPConfigClient) -> None:
|
||||||
|
self._c = client
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED START (do not hand-edit above this line) ----
|
||||||
|
# Regenerate with: python3 tools/gen_methods.py
|
||||||
|
|
||||||
|
def sites_aps_available_packages_list(self, params: Any = None) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_aps_available_packages_list``.
|
||||||
|
|
||||||
|
Source: ``aps.inc.php`` line 56.
|
||||||
|
PHP signature: ``sites_aps_available_packages_list($session_id, $params = array())``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_aps_available_packages_list", ("params", params))
|
||||||
|
|
||||||
|
def sites_aps_change_package_status(self, primary_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_aps_change_package_status``.
|
||||||
|
|
||||||
|
Source: ``aps.inc.php`` line 201.
|
||||||
|
PHP signature: ``sites_aps_change_package_status($session_id, $primary_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"sites_aps_change_package_status", ("primary_id", primary_id), ("params", params)
|
||||||
|
)
|
||||||
|
|
||||||
|
def sites_aps_get_package_details(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_aps_get_package_details``.
|
||||||
|
|
||||||
|
Source: ``aps.inc.php`` line 78.
|
||||||
|
PHP signature: ``sites_aps_get_package_details($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_aps_get_package_details", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_aps_get_package_file(self, primary_id: Any, filename: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_aps_get_package_file``.
|
||||||
|
|
||||||
|
Source: ``aps.inc.php`` line 118.
|
||||||
|
PHP signature: ``sites_aps_get_package_file($session_id, $primary_id, $filename)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_aps_get_package_file", ("primary_id", primary_id), ("filename", filename))
|
||||||
|
|
||||||
|
def sites_aps_get_package_settings(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_aps_get_package_settings``.
|
||||||
|
|
||||||
|
Source: ``aps.inc.php`` line 163.
|
||||||
|
PHP signature: ``sites_aps_get_package_settings($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_aps_get_package_settings", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_aps_install_package(self, primary_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_aps_install_package``.
|
||||||
|
|
||||||
|
Source: ``aps.inc.php`` line 231.
|
||||||
|
PHP signature: ``sites_aps_install_package($session_id, $primary_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_aps_install_package", ("primary_id", primary_id), ("params", params))
|
||||||
|
|
||||||
|
def sites_aps_instance_delete(self, primary_id: Any, params: Any = None) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_aps_instance_delete``.
|
||||||
|
|
||||||
|
Source: ``aps.inc.php`` line 331.
|
||||||
|
PHP signature: ``sites_aps_instance_delete($session_id, $primary_id, $params = array())``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_aps_instance_delete", ("primary_id", primary_id), ("params", params))
|
||||||
|
|
||||||
|
def sites_aps_instance_get(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_aps_instance_get``.
|
||||||
|
|
||||||
|
Source: ``aps.inc.php`` line 303.
|
||||||
|
PHP signature: ``sites_aps_instance_get($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_aps_instance_get", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_aps_instance_settings_get(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_aps_instance_settings_get``.
|
||||||
|
|
||||||
|
Source: ``aps.inc.php`` line 317.
|
||||||
|
PHP signature: ``sites_aps_instance_settings_get($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_aps_instance_settings_get", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_aps_update_package_list(self) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_aps_update_package_list``.
|
||||||
|
|
||||||
|
Source: ``aps.inc.php`` line 38.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_aps_update_package_list")
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED END ----
|
||||||
|
|
||||||
|
# ---- HAND-EDIT ONLY BELOW ----
|
||||||
59
src/ispconfig/backups.py
Normal file
59
src/ispconfig/backups.py
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
"""``backups.*`` — auto-generated ISPConfig remote-API wrappers.
|
||||||
|
|
||||||
|
This module is produced by ``tools/gen_methods.py`` from the
|
||||||
|
``tools/method_inventory.json`` catalog. Hand-edits go below the
|
||||||
|
``---- HAND-EDIT ONLY BELOW ----`` marker — they survive regeneration.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .client import ISPConfigClient
|
||||||
|
|
||||||
|
|
||||||
|
class BackupsModule:
|
||||||
|
"""Auto-generated module: Backups.
|
||||||
|
|
||||||
|
All methods below the ``AUTO-GENERATED START`` marker are produced
|
||||||
|
by ``tools/gen_methods.py``. Do not hand-edit that block — changes
|
||||||
|
will be overwritten on the next regeneration. Add helpers and
|
||||||
|
overrides below the ``HAND-EDIT ONLY BELOW`` marker instead.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, client: ISPConfigClient) -> None:
|
||||||
|
self._c = client
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED START (do not hand-edit above this line) ----
|
||||||
|
# Regenerate with: python3 tools/gen_methods.py
|
||||||
|
|
||||||
|
def sites_web_domain_backup(self, primary_id: Any, action_type: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_domain_backup``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 926.
|
||||||
|
PHP signature: ``sites_web_domain_backup($session_id, $primary_id, $action_type)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"sites_web_domain_backup", ("primary_id", primary_id), ("action_type", action_type)
|
||||||
|
)
|
||||||
|
|
||||||
|
def sites_web_domain_backup_list(self, site_id: Any = None) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_domain_backup_list``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 912.
|
||||||
|
PHP signature: ``sites_web_domain_backup_list($session_id, $site_id = null)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_web_domain_backup_list", ("site_id", site_id))
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED END ----
|
||||||
|
|
||||||
|
# ---- HAND-EDIT ONLY BELOW ----
|
||||||
|
|
@ -8,11 +8,23 @@ from typing import Any
|
||||||
|
|
||||||
from . import exceptions as _exc
|
from . import exceptions as _exc
|
||||||
from ._soap import SoapFault, SoapTransport
|
from ._soap import SoapFault, SoapTransport
|
||||||
|
from .admin import AdminModule
|
||||||
|
from .aps import ApsModule
|
||||||
|
from .backups import BackupsModule
|
||||||
from .clients import ClientsModule
|
from .clients import ClientsModule
|
||||||
|
from .cron import CronModule
|
||||||
from .databases import DatabasesModule
|
from .databases import DatabasesModule
|
||||||
from .dns import DnsModule
|
from .dns import DnsModule
|
||||||
|
from .domains import DomainsModule
|
||||||
|
from .ftp import FtpModule
|
||||||
from .mail import MailModule
|
from .mail import MailModule
|
||||||
|
from .misc import MiscModule
|
||||||
|
from .monitor import MonitorModule
|
||||||
|
from .openvz import OpenvzModule
|
||||||
|
from .server import ServerModule
|
||||||
|
from .shell import ShellModule
|
||||||
from .sites import SitesModule
|
from .sites import SitesModule
|
||||||
|
from .webdav import WebdavModule
|
||||||
|
|
||||||
log = logging.getLogger("ispconfig")
|
log = logging.getLogger("ispconfig")
|
||||||
|
|
||||||
|
|
@ -48,11 +60,26 @@ class ISPConfigClient:
|
||||||
self._transport = SoapTransport(url, verify_ssl=verify_ssl, timeout=timeout)
|
self._transport = SoapTransport(url, verify_ssl=verify_ssl, timeout=timeout)
|
||||||
self._session_id: str | None = None
|
self._session_id: str | None = None
|
||||||
|
|
||||||
|
# Hand-audited modules (stable API).
|
||||||
self.sites = SitesModule(self)
|
self.sites = SitesModule(self)
|
||||||
self.dns = DnsModule(self)
|
self.dns = DnsModule(self)
|
||||||
self.mail = MailModule(self)
|
self.mail = MailModule(self)
|
||||||
self.databases = DatabasesModule(self)
|
self.databases = DatabasesModule(self)
|
||||||
self.clients = ClientsModule(self)
|
self.clients = ClientsModule(self)
|
||||||
|
# Auto-generated modules (full surface, param shapes not yet
|
||||||
|
# verified in prod use — see per-method docstrings).
|
||||||
|
self.admin = AdminModule(self)
|
||||||
|
self.aps = ApsModule(self)
|
||||||
|
self.backups = BackupsModule(self)
|
||||||
|
self.cron = CronModule(self)
|
||||||
|
self.domains = DomainsModule(self)
|
||||||
|
self.ftp = FtpModule(self)
|
||||||
|
self.misc = MiscModule(self)
|
||||||
|
self.monitor = MonitorModule(self)
|
||||||
|
self.openvz = OpenvzModule(self)
|
||||||
|
self.server = ServerModule(self)
|
||||||
|
self.shell = ShellModule(self)
|
||||||
|
self.webdav = WebdavModule(self)
|
||||||
|
|
||||||
# ---- context manager ---------------------------------------------
|
# ---- context manager ---------------------------------------------
|
||||||
|
|
||||||
|
|
@ -105,6 +132,38 @@ class ISPConfigClient:
|
||||||
"""Read-only accessor — exposed for debugging, not for API calls."""
|
"""Read-only accessor — exposed for debugging, not for API calls."""
|
||||||
return self._session_id
|
return self._session_id
|
||||||
|
|
||||||
|
# ---- escape hatches ----------------------------------------------
|
||||||
|
|
||||||
|
def raw_call(self, method: str, *args: Any) -> Any:
|
||||||
|
"""Invoke an arbitrary ISPConfig remote method by name.
|
||||||
|
|
||||||
|
Use this when the SDK doesn't yet wrap the method you need —
|
||||||
|
newer ISPConfig versions may expose calls our inventory hasn't
|
||||||
|
caught up with. Args are passed positionally; names are cosmetic
|
||||||
|
on the wire, so we auto-number them as ``arg1``, ``arg2``, ...
|
||||||
|
|
||||||
|
If the call fails, capture ``FaultError.faultcode`` /
|
||||||
|
``FaultError.faultstring`` and file an issue against
|
||||||
|
``Sulkta-Coop/ispconfig-py`` so we can add the method properly.
|
||||||
|
"""
|
||||||
|
named_args = tuple((f"arg{i + 1}", v) for i, v in enumerate(args))
|
||||||
|
return self._call(method, *named_args)
|
||||||
|
|
||||||
|
def list_functions(self) -> list[str]:
|
||||||
|
"""Introspect the panel: return the list of remote methods it exposes.
|
||||||
|
|
||||||
|
Wrapper for ISPConfig's own ``get_function_list``. Handy when
|
||||||
|
checking whether your panel version supports a given call before
|
||||||
|
attempting it via :meth:`raw_call`.
|
||||||
|
"""
|
||||||
|
result = self._call("get_function_list")
|
||||||
|
if isinstance(result, list):
|
||||||
|
return [str(x) for x in result]
|
||||||
|
if isinstance(result, dict):
|
||||||
|
# Some versions return a map keyed by integer index.
|
||||||
|
return [str(v) for v in result.values()]
|
||||||
|
return []
|
||||||
|
|
||||||
# ---- the hot path ------------------------------------------------
|
# ---- the hot path ------------------------------------------------
|
||||||
|
|
||||||
def _call(self, method: str, *args: tuple[str, Any]) -> Any:
|
def _call(self, method: str, *args: tuple[str, Any]) -> Any:
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ ISPConfig's client model has two IDs you'll trip over:
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, cast
|
from typing import TYPE_CHECKING, Any, cast
|
||||||
|
|
||||||
from .types import Client
|
from .types import Client
|
||||||
|
|
||||||
|
|
@ -23,6 +23,284 @@ class ClientsModule:
|
||||||
def __init__(self, client: ISPConfigClient) -> None:
|
def __init__(self, client: ISPConfigClient) -> None:
|
||||||
self._c = client
|
self._c = client
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED START (do not hand-edit above this line) ----
|
||||||
|
# Regenerate with: python3 tools/gen_methods.py
|
||||||
|
|
||||||
|
def client_add(self, reseller_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``client_add``.
|
||||||
|
|
||||||
|
Source: ``client.inc.php`` line 157.
|
||||||
|
PHP signature: ``client_add($session_id, $reseller_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("client_add", ("reseller_id", reseller_id), ("params", params))
|
||||||
|
|
||||||
|
def client_change_password(self, client_id: Any, new_password: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Changes client password
|
||||||
|
|
||||||
|
Source: ``client.inc.php`` line 537.
|
||||||
|
PHP signature: ``client_change_password($session_id, $client_id, $new_password)``.
|
||||||
|
|
||||||
|
Params (from PHPDoc):
|
||||||
|
session (int): id
|
||||||
|
client (int): id
|
||||||
|
new (string): password
|
||||||
|
|
||||||
|
Returns: bool - true if success
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"client_change_password", ("client_id", client_id), ("new_password", new_password)
|
||||||
|
)
|
||||||
|
|
||||||
|
def client_delete(self, client_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``client_delete``.
|
||||||
|
|
||||||
|
Source: ``client.inc.php`` line 372.
|
||||||
|
PHP signature: ``client_delete($session_id, $client_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("client_delete", ("client_id", client_id))
|
||||||
|
|
||||||
|
def client_delete_everything(self, client_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``client_delete_everything``.
|
||||||
|
|
||||||
|
Source: ``client.inc.php`` line 390.
|
||||||
|
PHP signature: ``client_delete_everything($session_id, $client_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("client_delete_everything", ("client_id", client_id))
|
||||||
|
|
||||||
|
def client_get(self, client_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``client_get``.
|
||||||
|
|
||||||
|
Source: ``client.inc.php`` line 51.
|
||||||
|
PHP signature: ``client_get($session_id, $client_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("client_get", ("client_id", client_id))
|
||||||
|
|
||||||
|
def client_get_all(self) -> Any:
|
||||||
|
"""
|
||||||
|
Get All client_id's from database
|
||||||
|
|
||||||
|
Source: ``client.inc.php`` line 512.
|
||||||
|
|
||||||
|
Params (from PHPDoc):
|
||||||
|
|
||||||
|
Returns: Array - of all client_id's
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("client_get_all")
|
||||||
|
|
||||||
|
def client_get_by_customer_no(self, customer_no: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``client_get_by_customer_no``.
|
||||||
|
|
||||||
|
Source: ``client.inc.php`` line 485.
|
||||||
|
PHP signature: ``client_get_by_customer_no($session_id, $customer_no)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("client_get_by_customer_no", ("customer_no", customer_no))
|
||||||
|
|
||||||
|
def client_get_by_groupid(self, group_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``client_get_by_groupid``.
|
||||||
|
|
||||||
|
Source: ``client.inc.php`` line 688.
|
||||||
|
PHP signature: ``client_get_by_groupid($session_id, $group_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("client_get_by_groupid", ("group_id", group_id))
|
||||||
|
|
||||||
|
def client_get_by_username(self, username: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Get sys_user information by username
|
||||||
|
|
||||||
|
Source: ``client.inc.php`` line 469.
|
||||||
|
PHP signature: ``client_get_by_username($session_id, $username)``.
|
||||||
|
|
||||||
|
Params (from PHPDoc):
|
||||||
|
session (int): id
|
||||||
|
user (string): 's name
|
||||||
|
|
||||||
|
Returns: mixed - false if error
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("client_get_by_username", ("username", username))
|
||||||
|
|
||||||
|
def client_get_emailcontact(self, client_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``client_get_emailcontact``.
|
||||||
|
|
||||||
|
Source: ``client.inc.php`` line 118.
|
||||||
|
PHP signature: ``client_get_emailcontact($session_id, $client_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("client_get_emailcontact", ("client_id", client_id))
|
||||||
|
|
||||||
|
def client_get_groupid(self, client_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``client_get_groupid``.
|
||||||
|
|
||||||
|
Source: ``client.inc.php`` line 137.
|
||||||
|
PHP signature: ``client_get_groupid($session_id, $client_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("client_get_groupid", ("client_id", client_id))
|
||||||
|
|
||||||
|
def client_get_id(self, sys_userid: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``client_get_id``.
|
||||||
|
|
||||||
|
Source: ``client.inc.php`` line 96.
|
||||||
|
PHP signature: ``client_get_id($session_id, $sys_userid)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("client_get_id", ("sys_userid", sys_userid))
|
||||||
|
|
||||||
|
def client_get_sites_by_user(self, sys_userid: Any, sys_groupid: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Gets sites by $sys_userid & $sys_groupid
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 835.
|
||||||
|
PHP signature: ``client_get_sites_by_user($session_id, $sys_userid, $sys_groupid)``.
|
||||||
|
|
||||||
|
Params (from PHPDoc):
|
||||||
|
session (int): id
|
||||||
|
user (int): id
|
||||||
|
list (array): of groups
|
||||||
|
|
||||||
|
Returns: mixed - array with sites by user
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"client_get_sites_by_user", ("sys_userid", sys_userid), ("sys_groupid", sys_groupid)
|
||||||
|
)
|
||||||
|
|
||||||
|
def client_login_get(self, username: Any, password: Any, remote_ip: Any = "") -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``client_login_get``.
|
||||||
|
|
||||||
|
Source: ``client.inc.php`` line 576.
|
||||||
|
PHP signature: ``client_login_get($session_id,$username,$password,$remote_ip = '')``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"client_login_get", ("username", username), ("password", password), ("remote_ip", remote_ip)
|
||||||
|
)
|
||||||
|
|
||||||
|
def client_template_additional_add(self, client_id: Any, template_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``client_template_additional_add``.
|
||||||
|
|
||||||
|
Source: ``client.inc.php`` line 296.
|
||||||
|
PHP signature: ``client_template_additional_add($session_id, $client_id, $template_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"client_template_additional_add", ("client_id", client_id), ("template_id", template_id)
|
||||||
|
)
|
||||||
|
|
||||||
|
def client_template_additional_delete(self, client_id: Any, assigned_template_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``client_template_additional_delete``.
|
||||||
|
|
||||||
|
Source: ``client.inc.php`` line 334.
|
||||||
|
PHP signature: ``client_template_additional_delete($session_id, $client_id, $assigned_template_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"client_template_additional_delete",
|
||||||
|
("client_id", client_id),
|
||||||
|
("assigned_template_id", assigned_template_id),
|
||||||
|
)
|
||||||
|
|
||||||
|
def client_template_additional_get(self, client_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``client_template_additional_get``.
|
||||||
|
|
||||||
|
Source: ``client.inc.php`` line 258.
|
||||||
|
PHP signature: ``client_template_additional_get($session_id, $client_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("client_template_additional_get", ("client_id", client_id))
|
||||||
|
|
||||||
|
def client_templates_get_all(self) -> Any:
|
||||||
|
"""
|
||||||
|
Get all client templates
|
||||||
|
|
||||||
|
Source: ``client.inc.php`` line 566.
|
||||||
|
|
||||||
|
Params (from PHPDoc):
|
||||||
|
session (int): id
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("client_templates_get_all")
|
||||||
|
|
||||||
|
def client_update(self, client_id: Any, reseller_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``client_update``.
|
||||||
|
|
||||||
|
Source: ``client.inc.php`` line 187.
|
||||||
|
PHP signature: ``client_update($session_id, $client_id, $reseller_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"client_update", ("client_id", client_id), ("reseller_id", reseller_id), ("params", params)
|
||||||
|
)
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED END ----
|
||||||
|
|
||||||
|
# ---- HAND-EDIT ONLY BELOW ----
|
||||||
|
|
||||||
|
# ---- HAND-EDIT ONLY BELOW ----
|
||||||
|
|
||||||
|
# ---- HAND-EDIT ONLY BELOW ----
|
||||||
|
|
||||||
def get(self, primary_id: int) -> Client:
|
def get(self, primary_id: int) -> Client:
|
||||||
return cast(Client, self._c._call("client_get", ("primary_id", int(primary_id))))
|
return cast(Client, self._c._call("client_get", ("primary_id", int(primary_id))))
|
||||||
|
|
||||||
|
|
|
||||||
83
src/ispconfig/cron.py
Normal file
83
src/ispconfig/cron.py
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
"""``cron.*`` — auto-generated ISPConfig remote-API wrappers.
|
||||||
|
|
||||||
|
This module is produced by ``tools/gen_methods.py`` from the
|
||||||
|
``tools/method_inventory.json`` catalog. Hand-edits go below the
|
||||||
|
``---- HAND-EDIT ONLY BELOW ----`` marker — they survive regeneration.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .client import ISPConfigClient
|
||||||
|
|
||||||
|
|
||||||
|
class CronModule:
|
||||||
|
"""Auto-generated module: Cron.
|
||||||
|
|
||||||
|
All methods below the ``AUTO-GENERATED START`` marker are produced
|
||||||
|
by ``tools/gen_methods.py``. Do not hand-edit that block — changes
|
||||||
|
will be overwritten on the next regeneration. Add helpers and
|
||||||
|
overrides below the ``HAND-EDIT ONLY BELOW`` marker instead.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, client: ISPConfigClient) -> None:
|
||||||
|
self._c = client
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED START (do not hand-edit above this line) ----
|
||||||
|
# Regenerate with: python3 tools/gen_methods.py
|
||||||
|
|
||||||
|
def sites_cron_add(self, client_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_cron_add``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 59.
|
||||||
|
PHP signature: ``sites_cron_add($session_id, $client_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_cron_add", ("client_id", client_id), ("params", params))
|
||||||
|
|
||||||
|
def sites_cron_delete(self, cron_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_cron_delete``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 80.
|
||||||
|
PHP signature: ``sites_cron_delete($session_id, $cron_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_cron_delete", ("cron_id", cron_id))
|
||||||
|
|
||||||
|
def sites_cron_get(self, cron_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_cron_get``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 45.
|
||||||
|
PHP signature: ``sites_cron_get($session_id, $cron_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_cron_get", ("cron_id", cron_id))
|
||||||
|
|
||||||
|
def sites_cron_update(self, client_id: Any, cron_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_cron_update``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 69.
|
||||||
|
PHP signature: ``sites_cron_update($session_id, $client_id, $cron_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"sites_cron_update", ("client_id", client_id), ("cron_id", cron_id), ("params", params)
|
||||||
|
)
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED END ----
|
||||||
|
|
||||||
|
# ---- HAND-EDIT ONLY BELOW ----
|
||||||
|
|
@ -20,6 +20,132 @@ class DatabasesModule:
|
||||||
def __init__(self, client: ISPConfigClient) -> None:
|
def __init__(self, client: ISPConfigClient) -> None:
|
||||||
self._c = client
|
self._c = client
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED START (do not hand-edit above this line) ----
|
||||||
|
# Regenerate with: python3 tools/gen_methods.py
|
||||||
|
|
||||||
|
def sites_database_add(self, client_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_database_add``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 108.
|
||||||
|
PHP signature: ``sites_database_add($session_id, $client_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_database_add", ("client_id", client_id), ("params", params))
|
||||||
|
|
||||||
|
def sites_database_delete(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_database_delete``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 185.
|
||||||
|
PHP signature: ``sites_database_delete($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_database_delete", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_database_get(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_database_get``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 93.
|
||||||
|
PHP signature: ``sites_database_get($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_database_get", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_database_get_all_by_user(self, client_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Get all databases by user
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 898.
|
||||||
|
PHP signature: ``sites_database_get_all_by_user($session_id, $client_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_database_get_all_by_user", ("client_id", client_id))
|
||||||
|
|
||||||
|
def sites_database_update(self, client_id: Any, primary_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_database_update``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 151.
|
||||||
|
PHP signature: ``sites_database_update($session_id, $client_id, $primary_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"sites_database_update", ("client_id", client_id), ("primary_id", primary_id), ("params", params)
|
||||||
|
)
|
||||||
|
|
||||||
|
def sites_database_user_add(self, client_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_database_user_add``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 217.
|
||||||
|
PHP signature: ``sites_database_user_add($session_id, $client_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_database_user_add", ("client_id", client_id), ("params", params))
|
||||||
|
|
||||||
|
def sites_database_user_delete(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_database_user_delete``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 258.
|
||||||
|
PHP signature: ``sites_database_user_delete($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_database_user_delete", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_database_user_get(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_database_user_get``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 203.
|
||||||
|
PHP signature: ``sites_database_user_get($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_database_user_get", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_database_user_update(self, client_id: Any, primary_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_database_user_update``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 228.
|
||||||
|
PHP signature: ``sites_database_user_update($session_id, $client_id, $primary_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"sites_database_user_update",
|
||||||
|
("client_id", client_id),
|
||||||
|
("primary_id", primary_id),
|
||||||
|
("params", params),
|
||||||
|
)
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED END ----
|
||||||
|
|
||||||
|
# ---- HAND-EDIT ONLY BELOW ----
|
||||||
|
|
||||||
|
# ---- HAND-EDIT ONLY BELOW ----
|
||||||
|
|
||||||
|
# ---- HAND-EDIT ONLY BELOW ----
|
||||||
|
|
||||||
def get(self, primary_id: int) -> Database:
|
def get(self, primary_id: int) -> Database:
|
||||||
return self._c.sites.database_get(primary_id)
|
return self._c.sites.database_get(primary_id)
|
||||||
|
|
||||||
|
|
|
||||||
1363
src/ispconfig/dns.py
1363
src/ispconfig/dns.py
File diff suppressed because it is too large
Load diff
95
src/ispconfig/domains.py
Normal file
95
src/ispconfig/domains.py
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
"""``domains.*`` — auto-generated ISPConfig remote-API wrappers.
|
||||||
|
|
||||||
|
This module is produced by ``tools/gen_methods.py`` from the
|
||||||
|
``tools/method_inventory.json`` catalog. Hand-edits go below the
|
||||||
|
``---- HAND-EDIT ONLY BELOW ----`` marker — they survive regeneration.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .client import ISPConfigClient
|
||||||
|
|
||||||
|
|
||||||
|
class DomainsModule:
|
||||||
|
"""Auto-generated module: Domains.
|
||||||
|
|
||||||
|
All methods below the ``AUTO-GENERATED START`` marker are produced
|
||||||
|
by ``tools/gen_methods.py``. Do not hand-edit that block — changes
|
||||||
|
will be overwritten on the next regeneration. Add helpers and
|
||||||
|
overrides below the ``HAND-EDIT ONLY BELOW`` marker instead.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, client: ISPConfigClient) -> None:
|
||||||
|
self._c = client
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED START (do not hand-edit above this line) ----
|
||||||
|
# Regenerate with: python3 tools/gen_methods.py
|
||||||
|
|
||||||
|
def domains_domain_add(self, client_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``domains_domain_add``.
|
||||||
|
|
||||||
|
Source: ``domains.inc.php`` line 59.
|
||||||
|
PHP signature: ``domains_domain_add($session_id, $client_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("domains_domain_add", ("client_id", client_id), ("params", params))
|
||||||
|
|
||||||
|
def domains_domain_delete(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``domains_domain_delete``.
|
||||||
|
|
||||||
|
Source: ``domains.inc.php`` line 79.
|
||||||
|
PHP signature: ``domains_domain_delete($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("domains_domain_delete", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def domains_domain_get(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``domains_domain_get``.
|
||||||
|
|
||||||
|
Source: ``domains.inc.php`` line 45.
|
||||||
|
PHP signature: ``domains_domain_get($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("domains_domain_get", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def domains_domain_update(self, client_id: Any, primary_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``domains_domain_update``.
|
||||||
|
|
||||||
|
Source: ``domains.inc.php`` line 69.
|
||||||
|
PHP signature: ``domains_domain_update($session_id, $client_id, $primary_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"domains_domain_update", ("client_id", client_id), ("primary_id", primary_id), ("params", params)
|
||||||
|
)
|
||||||
|
|
||||||
|
def domains_get_all_by_user(self, group_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``domains_get_all_by_user``.
|
||||||
|
|
||||||
|
Source: ``domains.inc.php`` line 90.
|
||||||
|
PHP signature: ``domains_get_all_by_user($session_id, $group_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("domains_get_all_by_user", ("group_id", group_id))
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED END ----
|
||||||
|
|
||||||
|
# ---- HAND-EDIT ONLY BELOW ----
|
||||||
|
|
@ -47,11 +47,14 @@ def map_fault(faultcode: str, faultstring: str) -> ISPConfigError:
|
||||||
return AuthError(faultstring)
|
return AuthError(faultstring)
|
||||||
if "permission denied" in msg or "you do not have the permissions" in msg or "not allowed" in msg:
|
if "permission denied" in msg or "you do not have the permissions" in msg or "not allowed" in msg:
|
||||||
return PermissionError(faultstring)
|
return PermissionError(faultstring)
|
||||||
|
code_low = faultcode.lower()
|
||||||
if (
|
if (
|
||||||
"no records found" in msg
|
"no records found" in msg
|
||||||
or "not found" in msg
|
or "not found" in msg
|
||||||
or "no record found" in msg
|
or "no record found" in msg
|
||||||
or "no_domain_found" in faultcode.lower()
|
or "no_domain_found" in code_low
|
||||||
|
or "no_client_found" in code_low
|
||||||
|
or "no user account" in msg
|
||||||
or "invalid domain name" in msg
|
or "invalid domain name" in msg
|
||||||
):
|
):
|
||||||
return NotFoundError(faultstring)
|
return NotFoundError(faultstring)
|
||||||
|
|
|
||||||
95
src/ispconfig/ftp.py
Normal file
95
src/ispconfig/ftp.py
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
"""``ftp.*`` — auto-generated ISPConfig remote-API wrappers.
|
||||||
|
|
||||||
|
This module is produced by ``tools/gen_methods.py`` from the
|
||||||
|
``tools/method_inventory.json`` catalog. Hand-edits go below the
|
||||||
|
``---- HAND-EDIT ONLY BELOW ----`` marker — they survive regeneration.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .client import ISPConfigClient
|
||||||
|
|
||||||
|
|
||||||
|
class FtpModule:
|
||||||
|
"""Auto-generated module: Ftp.
|
||||||
|
|
||||||
|
All methods below the ``AUTO-GENERATED START`` marker are produced
|
||||||
|
by ``tools/gen_methods.py``. Do not hand-edit that block — changes
|
||||||
|
will be overwritten on the next regeneration. Add helpers and
|
||||||
|
overrides below the ``HAND-EDIT ONLY BELOW`` marker instead.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, client: ISPConfigClient) -> None:
|
||||||
|
self._c = client
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED START (do not hand-edit above this line) ----
|
||||||
|
# Regenerate with: python3 tools/gen_methods.py
|
||||||
|
|
||||||
|
def sites_ftp_user_add(self, client_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_ftp_user_add``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 300.
|
||||||
|
PHP signature: ``sites_ftp_user_add($session_id, $client_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_ftp_user_add", ("client_id", client_id), ("params", params))
|
||||||
|
|
||||||
|
def sites_ftp_user_delete(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_ftp_user_delete``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 321.
|
||||||
|
PHP signature: ``sites_ftp_user_delete($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_ftp_user_delete", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_ftp_user_get(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_ftp_user_get``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 286.
|
||||||
|
PHP signature: ``sites_ftp_user_get($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_ftp_user_get", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_ftp_user_server_get(self, ftp_user: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_ftp_user_server_get``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 332.
|
||||||
|
PHP signature: ``sites_ftp_user_server_get($session_id, $ftp_user)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_ftp_user_server_get", ("ftp_user", ftp_user))
|
||||||
|
|
||||||
|
def sites_ftp_user_update(self, client_id: Any, primary_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_ftp_user_update``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 310.
|
||||||
|
PHP signature: ``sites_ftp_user_update($session_id, $client_id, $primary_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"sites_ftp_user_update", ("client_id", client_id), ("primary_id", primary_id), ("params", params)
|
||||||
|
)
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED END ----
|
||||||
|
|
||||||
|
# ---- HAND-EDIT ONLY BELOW ----
|
||||||
File diff suppressed because it is too large
Load diff
81
src/ispconfig/misc.py
Normal file
81
src/ispconfig/misc.py
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
"""``misc.*`` — auto-generated ISPConfig remote-API wrappers.
|
||||||
|
|
||||||
|
This module is produced by ``tools/gen_methods.py`` from the
|
||||||
|
``tools/method_inventory.json`` catalog. Hand-edits go below the
|
||||||
|
``---- HAND-EDIT ONLY BELOW ----`` marker — they survive regeneration.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .client import ISPConfigClient
|
||||||
|
|
||||||
|
|
||||||
|
class MiscModule:
|
||||||
|
"""Auto-generated module: Misc.
|
||||||
|
|
||||||
|
All methods below the ``AUTO-GENERATED START`` marker are produced
|
||||||
|
by ``tools/gen_methods.py``. Do not hand-edit that block — changes
|
||||||
|
will be overwritten on the next regeneration. Add helpers and
|
||||||
|
overrides below the ``HAND-EDIT ONLY BELOW`` marker instead.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, client: ISPConfigClient) -> None:
|
||||||
|
self._c = client
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED START (do not hand-edit above this line) ----
|
||||||
|
# Regenerate with: python3 tools/gen_methods.py
|
||||||
|
|
||||||
|
def databasequota_get_by_user(self, client_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``databasequota_get_by_user``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 1012.
|
||||||
|
PHP signature: ``databasequota_get_by_user($session_id, $client_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("databasequota_get_by_user", ("client_id", client_id))
|
||||||
|
|
||||||
|
def ftptrafficquota_data(self, client_id: Any, lastdays: Any = 0) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``ftptrafficquota_data``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 997.
|
||||||
|
PHP signature: ``ftptrafficquota_data($session_id, $client_id, $lastdays = 0)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("ftptrafficquota_data", ("client_id", client_id), ("lastdays", lastdays))
|
||||||
|
|
||||||
|
def quota_get_by_user(self, client_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``quota_get_by_user``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 970.
|
||||||
|
PHP signature: ``quota_get_by_user($session_id, $client_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("quota_get_by_user", ("client_id", client_id))
|
||||||
|
|
||||||
|
def trafficquota_get_by_user(self, client_id: Any, lastdays: Any = 0) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``trafficquota_get_by_user``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 982.
|
||||||
|
PHP signature: ``trafficquota_get_by_user($session_id, $client_id, $lastdays = 0)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("trafficquota_get_by_user", ("client_id", client_id), ("lastdays", lastdays))
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED END ----
|
||||||
|
|
||||||
|
# ---- HAND-EDIT ONLY BELOW ----
|
||||||
45
src/ispconfig/monitor.py
Normal file
45
src/ispconfig/monitor.py
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
"""``monitor.*`` — auto-generated ISPConfig remote-API wrappers.
|
||||||
|
|
||||||
|
This module is produced by ``tools/gen_methods.py`` from the
|
||||||
|
``tools/method_inventory.json`` catalog. Hand-edits go below the
|
||||||
|
``---- HAND-EDIT ONLY BELOW ----`` marker — they survive regeneration.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .client import ISPConfigClient
|
||||||
|
|
||||||
|
|
||||||
|
class MonitorModule:
|
||||||
|
"""Auto-generated module: Monitor.
|
||||||
|
|
||||||
|
All methods below the ``AUTO-GENERATED START`` marker are produced
|
||||||
|
by ``tools/gen_methods.py``. Do not hand-edit that block — changes
|
||||||
|
will be overwritten on the next regeneration. Add helpers and
|
||||||
|
overrides below the ``HAND-EDIT ONLY BELOW`` marker instead.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, client: ISPConfigClient) -> None:
|
||||||
|
self._c = client
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED START (do not hand-edit above this line) ----
|
||||||
|
# Regenerate with: python3 tools/gen_methods.py
|
||||||
|
|
||||||
|
def monitor_jobqueue_count(self, server_id: Any = 0) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``monitor_jobqueue_count``.
|
||||||
|
|
||||||
|
Source: ``monitor.inc.php`` line 36.
|
||||||
|
PHP signature: ``monitor_jobqueue_count($session_id, $server_id = 0)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("monitor_jobqueue_count", ("server_id", server_id))
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED END ----
|
||||||
|
|
||||||
|
# ---- HAND-EDIT ONLY BELOW ----
|
||||||
319
src/ispconfig/openvz.py
Normal file
319
src/ispconfig/openvz.py
Normal file
|
|
@ -0,0 +1,319 @@
|
||||||
|
"""``openvz.*`` — auto-generated ISPConfig remote-API wrappers.
|
||||||
|
|
||||||
|
This module is produced by ``tools/gen_methods.py`` from the
|
||||||
|
``tools/method_inventory.json`` catalog. Hand-edits go below the
|
||||||
|
``---- HAND-EDIT ONLY BELOW ----`` marker — they survive regeneration.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .client import ISPConfigClient
|
||||||
|
|
||||||
|
|
||||||
|
class OpenvzModule:
|
||||||
|
"""Auto-generated module: Openvz.
|
||||||
|
|
||||||
|
All methods below the ``AUTO-GENERATED START`` marker are produced
|
||||||
|
by ``tools/gen_methods.py``. Do not hand-edit that block — changes
|
||||||
|
will be overwritten on the next regeneration. Add helpers and
|
||||||
|
overrides below the ``HAND-EDIT ONLY BELOW`` marker instead.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, client: ISPConfigClient) -> None:
|
||||||
|
self._c = client
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED START (do not hand-edit above this line) ----
|
||||||
|
# Regenerate with: python3 tools/gen_methods.py
|
||||||
|
|
||||||
|
def openvz_get_free_ip(self, server_id: Any = 0) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``openvz_get_free_ip``.
|
||||||
|
|
||||||
|
Source: ``openvz.inc.php`` line 151.
|
||||||
|
PHP signature: ``openvz_get_free_ip($session_id, $server_id = 0)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("openvz_get_free_ip", ("server_id", server_id))
|
||||||
|
|
||||||
|
def openvz_ip_add(self, client_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``openvz_ip_add``.
|
||||||
|
|
||||||
|
Source: ``openvz.inc.php`` line 175.
|
||||||
|
PHP signature: ``openvz_ip_add($session_id, $client_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("openvz_ip_add", ("client_id", client_id), ("params", params))
|
||||||
|
|
||||||
|
def openvz_ip_delete(self, ip_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``openvz_ip_delete``.
|
||||||
|
|
||||||
|
Source: ``openvz.inc.php`` line 196.
|
||||||
|
PHP signature: ``openvz_ip_delete($session_id, $ip_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("openvz_ip_delete", ("ip_id", ip_id))
|
||||||
|
|
||||||
|
def openvz_ip_get(self, ip_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``openvz_ip_get``.
|
||||||
|
|
||||||
|
Source: ``openvz.inc.php`` line 137.
|
||||||
|
PHP signature: ``openvz_ip_get($session_id, $ip_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("openvz_ip_get", ("ip_id", ip_id))
|
||||||
|
|
||||||
|
def openvz_ip_update(self, client_id: Any, ip_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``openvz_ip_update``.
|
||||||
|
|
||||||
|
Source: ``openvz.inc.php`` line 185.
|
||||||
|
PHP signature: ``openvz_ip_update($session_id, $client_id, $ip_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"openvz_ip_update", ("client_id", client_id), ("ip_id", ip_id), ("params", params)
|
||||||
|
)
|
||||||
|
|
||||||
|
def openvz_ostemplate_add(self, client_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``openvz_ostemplate_add``.
|
||||||
|
|
||||||
|
Source: ``openvz.inc.php`` line 59.
|
||||||
|
PHP signature: ``openvz_ostemplate_add($session_id, $client_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("openvz_ostemplate_add", ("client_id", client_id), ("params", params))
|
||||||
|
|
||||||
|
def openvz_ostemplate_delete(self, ostemplate_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``openvz_ostemplate_delete``.
|
||||||
|
|
||||||
|
Source: ``openvz.inc.php`` line 80.
|
||||||
|
PHP signature: ``openvz_ostemplate_delete($session_id, $ostemplate_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("openvz_ostemplate_delete", ("ostemplate_id", ostemplate_id))
|
||||||
|
|
||||||
|
def openvz_ostemplate_get(self, ostemplate_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``openvz_ostemplate_get``.
|
||||||
|
|
||||||
|
Source: ``openvz.inc.php`` line 45.
|
||||||
|
PHP signature: ``openvz_ostemplate_get($session_id, $ostemplate_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("openvz_ostemplate_get", ("ostemplate_id", ostemplate_id))
|
||||||
|
|
||||||
|
def openvz_ostemplate_update(self, client_id: Any, ostemplate_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``openvz_ostemplate_update``.
|
||||||
|
|
||||||
|
Source: ``openvz.inc.php`` line 69.
|
||||||
|
PHP signature: ``openvz_ostemplate_update($session_id, $client_id, $ostemplate_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"openvz_ostemplate_update",
|
||||||
|
("client_id", client_id),
|
||||||
|
("ostemplate_id", ostemplate_id),
|
||||||
|
("params", params),
|
||||||
|
)
|
||||||
|
|
||||||
|
def openvz_template_add(self, client_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``openvz_template_add``.
|
||||||
|
|
||||||
|
Source: ``openvz.inc.php`` line 105.
|
||||||
|
PHP signature: ``openvz_template_add($session_id, $client_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("openvz_template_add", ("client_id", client_id), ("params", params))
|
||||||
|
|
||||||
|
def openvz_template_delete(self, template_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``openvz_template_delete``.
|
||||||
|
|
||||||
|
Source: ``openvz.inc.php`` line 126.
|
||||||
|
PHP signature: ``openvz_template_delete($session_id, $template_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("openvz_template_delete", ("template_id", template_id))
|
||||||
|
|
||||||
|
def openvz_template_get(self, template_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``openvz_template_get``.
|
||||||
|
|
||||||
|
Source: ``openvz.inc.php`` line 91.
|
||||||
|
PHP signature: ``openvz_template_get($session_id, $template_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("openvz_template_get", ("template_id", template_id))
|
||||||
|
|
||||||
|
def openvz_template_update(self, client_id: Any, template_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``openvz_template_update``.
|
||||||
|
|
||||||
|
Source: ``openvz.inc.php`` line 115.
|
||||||
|
PHP signature: ``openvz_template_update($session_id, $client_id, $template_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"openvz_template_update",
|
||||||
|
("client_id", client_id),
|
||||||
|
("template_id", template_id),
|
||||||
|
("params", params),
|
||||||
|
)
|
||||||
|
|
||||||
|
def openvz_vm_add(self, client_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``openvz_vm_add``.
|
||||||
|
|
||||||
|
Source: ``openvz.inc.php`` line 241.
|
||||||
|
PHP signature: ``openvz_vm_add($session_id, $client_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("openvz_vm_add", ("client_id", client_id), ("params", params))
|
||||||
|
|
||||||
|
def openvz_vm_add_from_template(
|
||||||
|
self, client_id: Any, ostemplate_id: Any, template_id: Any, override_params: Any = None
|
||||||
|
) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``openvz_vm_add_from_template``.
|
||||||
|
|
||||||
|
Source: ``openvz.inc.php`` line 251.
|
||||||
|
PHP signature: ``openvz_vm_add_from_template($session_id, $client_id, $ostemplate_id, $template_id, $override_params = array())``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"openvz_vm_add_from_template",
|
||||||
|
("client_id", client_id),
|
||||||
|
("ostemplate_id", ostemplate_id),
|
||||||
|
("template_id", template_id),
|
||||||
|
("override_params", override_params),
|
||||||
|
)
|
||||||
|
|
||||||
|
def openvz_vm_delete(self, vm_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``openvz_vm_delete``.
|
||||||
|
|
||||||
|
Source: ``openvz.inc.php`` line 342.
|
||||||
|
PHP signature: ``openvz_vm_delete($session_id, $vm_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("openvz_vm_delete", ("vm_id", vm_id))
|
||||||
|
|
||||||
|
def openvz_vm_get(self, vm_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``openvz_vm_get``.
|
||||||
|
|
||||||
|
Source: ``openvz.inc.php`` line 207.
|
||||||
|
PHP signature: ``openvz_vm_get($session_id, $vm_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("openvz_vm_get", ("vm_id", vm_id))
|
||||||
|
|
||||||
|
def openvz_vm_get_by_client(self, client_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``openvz_vm_get_by_client``.
|
||||||
|
|
||||||
|
Source: ``openvz.inc.php`` line 221.
|
||||||
|
PHP signature: ``openvz_vm_get_by_client($session_id, $client_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("openvz_vm_get_by_client", ("client_id", client_id))
|
||||||
|
|
||||||
|
def openvz_vm_restart(self, vm_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``openvz_vm_restart``.
|
||||||
|
|
||||||
|
Source: ``openvz.inc.php`` line 437.
|
||||||
|
PHP signature: ``openvz_vm_restart($session_id, $vm_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("openvz_vm_restart", ("vm_id", vm_id))
|
||||||
|
|
||||||
|
def openvz_vm_start(self, vm_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``openvz_vm_start``.
|
||||||
|
|
||||||
|
Source: ``openvz.inc.php`` line 353.
|
||||||
|
PHP signature: ``openvz_vm_start($session_id, $vm_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("openvz_vm_start", ("vm_id", vm_id))
|
||||||
|
|
||||||
|
def openvz_vm_stop(self, vm_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``openvz_vm_stop``.
|
||||||
|
|
||||||
|
Source: ``openvz.inc.php`` line 395.
|
||||||
|
PHP signature: ``openvz_vm_stop($session_id, $vm_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("openvz_vm_stop", ("vm_id", vm_id))
|
||||||
|
|
||||||
|
def openvz_vm_update(self, client_id: Any, vm_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``openvz_vm_update``.
|
||||||
|
|
||||||
|
Source: ``openvz.inc.php`` line 331.
|
||||||
|
PHP signature: ``openvz_vm_update($session_id, $client_id, $vm_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"openvz_vm_update", ("client_id", client_id), ("vm_id", vm_id), ("params", params)
|
||||||
|
)
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED END ----
|
||||||
|
|
||||||
|
# ---- HAND-EDIT ONLY BELOW ----
|
||||||
215
src/ispconfig/server.py
Normal file
215
src/ispconfig/server.py
Normal file
|
|
@ -0,0 +1,215 @@
|
||||||
|
"""``server.*`` — auto-generated ISPConfig remote-API wrappers.
|
||||||
|
|
||||||
|
This module is produced by ``tools/gen_methods.py`` from the
|
||||||
|
``tools/method_inventory.json`` catalog. Hand-edits go below the
|
||||||
|
``---- HAND-EDIT ONLY BELOW ----`` marker — they survive regeneration.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .client import ISPConfigClient
|
||||||
|
|
||||||
|
|
||||||
|
class ServerModule:
|
||||||
|
"""Auto-generated module: Server.
|
||||||
|
|
||||||
|
All methods below the ``AUTO-GENERATED START`` marker are produced
|
||||||
|
by ``tools/gen_methods.py``. Do not hand-edit that block — changes
|
||||||
|
will be overwritten on the next regeneration. Add helpers and
|
||||||
|
overrides below the ``HAND-EDIT ONLY BELOW`` marker instead.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, client: ISPConfigClient) -> None:
|
||||||
|
self._c = client
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED START (do not hand-edit above this line) ----
|
||||||
|
# Regenerate with: python3 tools/gen_methods.py
|
||||||
|
|
||||||
|
def server_config_set(self, server_id: Any, section: str, key: str, value: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Set a value in the server configuration
|
||||||
|
|
||||||
|
Source: ``server.inc.php`` line 153.
|
||||||
|
PHP signature: ``server_config_set($session_id, $server_id, $section, $key, $value)``.
|
||||||
|
|
||||||
|
Params (from PHPDoc):
|
||||||
|
session (int): id
|
||||||
|
server (int): id
|
||||||
|
section (string): of the config field in the server table. Could be 'web', 'dns', 'mail', 'dns', 'cron', etc
|
||||||
|
key (string): of the option that you want to set
|
||||||
|
option (string): value that you want to set
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"server_config_set",
|
||||||
|
("server_id", server_id),
|
||||||
|
("section", section),
|
||||||
|
("key", key),
|
||||||
|
("value", value),
|
||||||
|
)
|
||||||
|
|
||||||
|
def server_get(self, server_id: Any = None, section: str = "") -> Any:
|
||||||
|
"""
|
||||||
|
Gets the server configuration
|
||||||
|
|
||||||
|
Source: ``server.inc.php`` line 116.
|
||||||
|
PHP signature: ``server_get($session_id, $server_id = null, $section ='')``.
|
||||||
|
|
||||||
|
Params (from PHPDoc):
|
||||||
|
session (int): id
|
||||||
|
server (int): id
|
||||||
|
section (string): of the config field in the server table. Could be 'web', 'dns', 'mail', 'dns', 'cron', etc
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("server_get", ("server_id", server_id), ("section", section))
|
||||||
|
|
||||||
|
def server_get_all(self) -> Any:
|
||||||
|
"""
|
||||||
|
Gets a list of all servers
|
||||||
|
|
||||||
|
Source: ``server.inc.php`` line 179.
|
||||||
|
|
||||||
|
Params (from PHPDoc):
|
||||||
|
server_name (int)
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("server_get_all")
|
||||||
|
|
||||||
|
def server_get_app_version(self, server_id: Any = 0) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``server_get_app_version``.
|
||||||
|
|
||||||
|
Source: ``server.inc.php`` line 238.
|
||||||
|
PHP signature: ``server_get_app_version($session_id, $server_id = 0)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("server_get_app_version", ("server_id", server_id))
|
||||||
|
|
||||||
|
def server_get_functions(self, server_id: int) -> Any:
|
||||||
|
"""
|
||||||
|
Gets the functions of a server by server_id
|
||||||
|
|
||||||
|
Source: ``server.inc.php`` line 223.
|
||||||
|
PHP signature: ``server_get_functions($session_id, $server_id)``.
|
||||||
|
|
||||||
|
Params (from PHPDoc):
|
||||||
|
server_id (int)
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("server_get_functions", ("server_id", server_id))
|
||||||
|
|
||||||
|
def server_get_php_versions(self, server_id: Any, php: Any, get_full_data: Any = False) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``server_get_php_versions``.
|
||||||
|
|
||||||
|
Source: ``server.inc.php`` line 259.
|
||||||
|
PHP signature: ``server_get_php_versions($session_id, $server_id, $php, $get_full_data = false)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"server_get_php_versions",
|
||||||
|
("server_id", server_id),
|
||||||
|
("php", php),
|
||||||
|
("get_full_data", get_full_data),
|
||||||
|
)
|
||||||
|
|
||||||
|
def server_get_serverid_by_ip(self, ipaddress: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Gets the server configuration
|
||||||
|
|
||||||
|
Source: ``server.inc.php`` line 49.
|
||||||
|
PHP signature: ``server_get_serverid_by_ip($session_id, $ipaddress)``.
|
||||||
|
|
||||||
|
Params (from PHPDoc):
|
||||||
|
session (int): id
|
||||||
|
server (int): id
|
||||||
|
section (string): of the config field in the server table. Could be 'web', 'dns', 'mail', 'dns', 'cron', etc
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("server_get_serverid_by_ip", ("ipaddress", ipaddress))
|
||||||
|
|
||||||
|
def server_get_serverid_by_name(self, server_name: int) -> Any:
|
||||||
|
"""
|
||||||
|
Gets the server_id by server_name
|
||||||
|
|
||||||
|
Source: ``server.inc.php`` line 201.
|
||||||
|
PHP signature: ``server_get_serverid_by_name($session_id, $server_name)``.
|
||||||
|
|
||||||
|
Params (from PHPDoc):
|
||||||
|
server_name (int)
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("server_get_serverid_by_name", ("server_name", server_name))
|
||||||
|
|
||||||
|
def server_ip_add(self, client_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``server_ip_add``.
|
||||||
|
|
||||||
|
Source: ``server.inc.php`` line 78.
|
||||||
|
PHP signature: ``server_ip_add($session_id, $client_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("server_ip_add", ("client_id", client_id), ("params", params))
|
||||||
|
|
||||||
|
def server_ip_delete(self, ip_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``server_ip_delete``.
|
||||||
|
|
||||||
|
Source: ``server.inc.php`` line 99.
|
||||||
|
PHP signature: ``server_ip_delete($session_id, $ip_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("server_ip_delete", ("ip_id", ip_id))
|
||||||
|
|
||||||
|
def server_ip_get(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``server_ip_get``.
|
||||||
|
|
||||||
|
Source: ``server.inc.php`` line 64.
|
||||||
|
PHP signature: ``server_ip_get($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("server_ip_get", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def server_ip_update(self, client_id: Any, ip_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``server_ip_update``.
|
||||||
|
|
||||||
|
Source: ``server.inc.php`` line 88.
|
||||||
|
PHP signature: ``server_ip_update($session_id, $client_id, $ip_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"server_ip_update", ("client_id", client_id), ("ip_id", ip_id), ("params", params)
|
||||||
|
)
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED END ----
|
||||||
|
|
||||||
|
# ---- HAND-EDIT ONLY BELOW ----
|
||||||
86
src/ispconfig/shell.py
Normal file
86
src/ispconfig/shell.py
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
"""``shell.*`` — auto-generated ISPConfig remote-API wrappers.
|
||||||
|
|
||||||
|
This module is produced by ``tools/gen_methods.py`` from the
|
||||||
|
``tools/method_inventory.json`` catalog. Hand-edits go below the
|
||||||
|
``---- HAND-EDIT ONLY BELOW ----`` marker — they survive regeneration.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .client import ISPConfigClient
|
||||||
|
|
||||||
|
|
||||||
|
class ShellModule:
|
||||||
|
"""Auto-generated module: Shell.
|
||||||
|
|
||||||
|
All methods below the ``AUTO-GENERATED START`` marker are produced
|
||||||
|
by ``tools/gen_methods.py``. Do not hand-edit that block — changes
|
||||||
|
will be overwritten on the next regeneration. Add helpers and
|
||||||
|
overrides below the ``HAND-EDIT ONLY BELOW`` marker instead.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, client: ISPConfigClient) -> None:
|
||||||
|
self._c = client
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED START (do not hand-edit above this line) ----
|
||||||
|
# Regenerate with: python3 tools/gen_methods.py
|
||||||
|
|
||||||
|
def sites_shell_user_add(self, client_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_shell_user_add``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 368.
|
||||||
|
PHP signature: ``sites_shell_user_add($session_id, $client_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_shell_user_add", ("client_id", client_id), ("params", params))
|
||||||
|
|
||||||
|
def sites_shell_user_delete(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_shell_user_delete``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 389.
|
||||||
|
PHP signature: ``sites_shell_user_delete($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_shell_user_delete", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_shell_user_get(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_shell_user_get``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 354.
|
||||||
|
PHP signature: ``sites_shell_user_get($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_shell_user_get", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_shell_user_update(self, client_id: Any, primary_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_shell_user_update``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 378.
|
||||||
|
PHP signature: ``sites_shell_user_update($session_id, $client_id, $primary_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"sites_shell_user_update",
|
||||||
|
("client_id", client_id),
|
||||||
|
("primary_id", primary_id),
|
||||||
|
("params", params),
|
||||||
|
)
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED END ----
|
||||||
|
|
||||||
|
# ---- HAND-EDIT ONLY BELOW ----
|
||||||
|
|
@ -31,6 +31,409 @@ class SitesModule:
|
||||||
def __init__(self, client: ISPConfigClient) -> None:
|
def __init__(self, client: ISPConfigClient) -> None:
|
||||||
self._c = client
|
self._c = client
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED START (do not hand-edit above this line) ----
|
||||||
|
# Regenerate with: python3 tools/gen_methods.py
|
||||||
|
|
||||||
|
def sites_web_aliasdomain_add(self, client_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_aliasdomain_add``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 642.
|
||||||
|
PHP signature: ``sites_web_aliasdomain_add($session_id, $client_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_web_aliasdomain_add", ("client_id", client_id), ("params", params))
|
||||||
|
|
||||||
|
def sites_web_aliasdomain_delete(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_aliasdomain_delete``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 663.
|
||||||
|
PHP signature: ``sites_web_aliasdomain_delete($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_web_aliasdomain_delete", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_web_aliasdomain_get(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_aliasdomain_get``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 628.
|
||||||
|
PHP signature: ``sites_web_aliasdomain_get($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_web_aliasdomain_get", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_web_aliasdomain_update(self, client_id: Any, primary_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_aliasdomain_update``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 652.
|
||||||
|
PHP signature: ``sites_web_aliasdomain_update($session_id, $client_id, $primary_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"sites_web_aliasdomain_update",
|
||||||
|
("client_id", client_id),
|
||||||
|
("primary_id", primary_id),
|
||||||
|
("params", params),
|
||||||
|
)
|
||||||
|
|
||||||
|
def sites_web_domain_add(self, client_id: Any, params: Any, readonly: Any = False) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_domain_add``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 416.
|
||||||
|
PHP signature: ``sites_web_domain_add($session_id, $client_id, $params, $readonly = false)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"sites_web_domain_add", ("client_id", client_id), ("params", params), ("readonly", readonly)
|
||||||
|
)
|
||||||
|
|
||||||
|
def sites_web_domain_delete(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_domain_delete``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 471.
|
||||||
|
PHP signature: ``sites_web_domain_delete($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_web_domain_delete", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_web_domain_get(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_domain_get``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 402.
|
||||||
|
PHP signature: ``sites_web_domain_get($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_web_domain_get", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_web_domain_set_status(self, primary_id: Any, status: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Change domains status
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 870.
|
||||||
|
PHP signature: ``sites_web_domain_set_status($session_id, $primary_id, $status)``.
|
||||||
|
|
||||||
|
Params (from PHPDoc):
|
||||||
|
session (int): id
|
||||||
|
site (int): id
|
||||||
|
active (string): or inactive string
|
||||||
|
|
||||||
|
Returns: mixed - false if error
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_web_domain_set_status", ("primary_id", primary_id), ("status", status))
|
||||||
|
|
||||||
|
def sites_web_domain_update(self, client_id: Any, primary_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_domain_update``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 451.
|
||||||
|
PHP signature: ``sites_web_domain_update($session_id, $client_id, $primary_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"sites_web_domain_update",
|
||||||
|
("client_id", client_id),
|
||||||
|
("primary_id", primary_id),
|
||||||
|
("params", params),
|
||||||
|
)
|
||||||
|
|
||||||
|
def sites_web_folder_add(self, client_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_folder_add``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 738.
|
||||||
|
PHP signature: ``sites_web_folder_add($session_id, $client_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_web_folder_add", ("client_id", client_id), ("params", params))
|
||||||
|
|
||||||
|
def sites_web_folder_delete(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_folder_delete``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 759.
|
||||||
|
PHP signature: ``sites_web_folder_delete($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_web_folder_delete", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_web_folder_get(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_folder_get``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 724.
|
||||||
|
PHP signature: ``sites_web_folder_get($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_web_folder_get", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_web_folder_update(self, client_id: Any, primary_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_folder_update``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 748.
|
||||||
|
PHP signature: ``sites_web_folder_update($session_id, $client_id, $primary_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"sites_web_folder_update",
|
||||||
|
("client_id", client_id),
|
||||||
|
("primary_id", primary_id),
|
||||||
|
("params", params),
|
||||||
|
)
|
||||||
|
|
||||||
|
def sites_web_folder_user_add(self, client_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_folder_user_add``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 796.
|
||||||
|
PHP signature: ``sites_web_folder_user_add($session_id, $client_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_web_folder_user_add", ("client_id", client_id), ("params", params))
|
||||||
|
|
||||||
|
def sites_web_folder_user_delete(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_folder_user_delete``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 817.
|
||||||
|
PHP signature: ``sites_web_folder_user_delete($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_web_folder_user_delete", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_web_folder_user_get(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_folder_user_get``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 782.
|
||||||
|
PHP signature: ``sites_web_folder_user_get($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_web_folder_user_get", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_web_folder_user_update(self, client_id: Any, primary_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_folder_user_update``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 806.
|
||||||
|
PHP signature: ``sites_web_folder_user_update($session_id, $client_id, $primary_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"sites_web_folder_user_update",
|
||||||
|
("client_id", client_id),
|
||||||
|
("primary_id", primary_id),
|
||||||
|
("params", params),
|
||||||
|
)
|
||||||
|
|
||||||
|
def sites_web_subdomain_add(self, client_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_subdomain_add``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 690.
|
||||||
|
PHP signature: ``sites_web_subdomain_add($session_id, $client_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_web_subdomain_add", ("client_id", client_id), ("params", params))
|
||||||
|
|
||||||
|
def sites_web_subdomain_delete(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_subdomain_delete``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 711.
|
||||||
|
PHP signature: ``sites_web_subdomain_delete($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_web_subdomain_delete", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_web_subdomain_get(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_subdomain_get``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 676.
|
||||||
|
PHP signature: ``sites_web_subdomain_get($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_web_subdomain_get", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_web_subdomain_update(self, client_id: Any, primary_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_subdomain_update``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 700.
|
||||||
|
PHP signature: ``sites_web_subdomain_update($session_id, $client_id, $primary_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"sites_web_subdomain_update",
|
||||||
|
("client_id", client_id),
|
||||||
|
("primary_id", primary_id),
|
||||||
|
("params", params),
|
||||||
|
)
|
||||||
|
|
||||||
|
def sites_web_vhost_aliasdomain_add(self, client_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_vhost_aliasdomain_add``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 498.
|
||||||
|
PHP signature: ``sites_web_vhost_aliasdomain_add($session_id, $client_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_web_vhost_aliasdomain_add", ("client_id", client_id), ("params", params))
|
||||||
|
|
||||||
|
def sites_web_vhost_aliasdomain_delete(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_vhost_aliasdomain_delete``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 543.
|
||||||
|
PHP signature: ``sites_web_vhost_aliasdomain_delete($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_web_vhost_aliasdomain_delete", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_web_vhost_aliasdomain_get(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_vhost_aliasdomain_get``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 484.
|
||||||
|
PHP signature: ``sites_web_vhost_aliasdomain_get($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_web_vhost_aliasdomain_get", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_web_vhost_aliasdomain_update(self, client_id: Any, primary_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_vhost_aliasdomain_update``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 523.
|
||||||
|
PHP signature: ``sites_web_vhost_aliasdomain_update($session_id, $client_id, $primary_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"sites_web_vhost_aliasdomain_update",
|
||||||
|
("client_id", client_id),
|
||||||
|
("primary_id", primary_id),
|
||||||
|
("params", params),
|
||||||
|
)
|
||||||
|
|
||||||
|
def sites_web_vhost_subdomain_add(self, client_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_vhost_subdomain_add``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 570.
|
||||||
|
PHP signature: ``sites_web_vhost_subdomain_add($session_id, $client_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_web_vhost_subdomain_add", ("client_id", client_id), ("params", params))
|
||||||
|
|
||||||
|
def sites_web_vhost_subdomain_delete(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_vhost_subdomain_delete``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 615.
|
||||||
|
PHP signature: ``sites_web_vhost_subdomain_delete($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_web_vhost_subdomain_delete", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_web_vhost_subdomain_get(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_vhost_subdomain_get``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 556.
|
||||||
|
PHP signature: ``sites_web_vhost_subdomain_get($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_web_vhost_subdomain_get", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_web_vhost_subdomain_update(self, client_id: Any, primary_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_web_vhost_subdomain_update``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 595.
|
||||||
|
PHP signature: ``sites_web_vhost_subdomain_update($session_id, $client_id, $primary_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"sites_web_vhost_subdomain_update",
|
||||||
|
("client_id", client_id),
|
||||||
|
("primary_id", primary_id),
|
||||||
|
("params", params),
|
||||||
|
)
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED END ----
|
||||||
|
|
||||||
|
# ---- HAND-EDIT ONLY BELOW ----
|
||||||
|
|
||||||
|
# ---- HAND-EDIT ONLY BELOW ----
|
||||||
|
|
||||||
|
# ---- HAND-EDIT ONLY BELOW ----
|
||||||
|
|
||||||
# ---- web domain ---------------------------------------------------
|
# ---- web domain ---------------------------------------------------
|
||||||
|
|
||||||
def web_domain_get(self, primary_id: int) -> WebDomain:
|
def web_domain_get(self, primary_id: int) -> WebDomain:
|
||||||
|
|
@ -42,12 +445,14 @@ class SitesModule:
|
||||||
|
|
||||||
``client_id=0`` creates an admin-owned site.
|
``client_id=0`` creates an admin-owned site.
|
||||||
"""
|
"""
|
||||||
return int(self._c._call(
|
return int(
|
||||||
"sites_web_domain_add",
|
self._c._call(
|
||||||
("client_id", int(client_id)),
|
"sites_web_domain_add",
|
||||||
("params", dict(params)),
|
("client_id", int(client_id)),
|
||||||
("read_only", bool(read_only)),
|
("params", dict(params)),
|
||||||
))
|
("read_only", bool(read_only)),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def web_domain_update(self, client_id: int, primary_id: int, params: Mapping[str, Any]) -> int:
|
def web_domain_update(self, client_id: int, primary_id: int, params: Mapping[str, Any]) -> int:
|
||||||
"""Update a site.
|
"""Update a site.
|
||||||
|
|
@ -56,23 +461,27 @@ class SitesModule:
|
||||||
The second positional arg is ``client_id``, not ``primary_id``.
|
The second positional arg is ``client_id``, not ``primary_id``.
|
||||||
Pass 0 for admin-owned. See module docstring.
|
Pass 0 for admin-owned. See module docstring.
|
||||||
"""
|
"""
|
||||||
return int(self._c._call(
|
return int(
|
||||||
"sites_web_domain_update",
|
self._c._call(
|
||||||
("client_id", int(client_id)),
|
"sites_web_domain_update",
|
||||||
("primary_id", int(primary_id)),
|
("client_id", int(client_id)),
|
||||||
("params", dict(params)),
|
("primary_id", int(primary_id)),
|
||||||
))
|
("params", dict(params)),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def web_domain_delete(self, primary_id: int) -> int:
|
def web_domain_delete(self, primary_id: int) -> int:
|
||||||
return int(self._c._call("sites_web_domain_delete", ("primary_id", int(primary_id))))
|
return int(self._c._call("sites_web_domain_delete", ("primary_id", int(primary_id))))
|
||||||
|
|
||||||
def web_domain_set_status(self, primary_id: int, status: str) -> int:
|
def web_domain_set_status(self, primary_id: int, status: str) -> int:
|
||||||
"""``status`` is typically ``'active'`` or ``'inactive'``."""
|
"""``status`` is typically ``'active'`` or ``'inactive'``."""
|
||||||
return int(self._c._call(
|
return int(
|
||||||
"sites_web_domain_set_status",
|
self._c._call(
|
||||||
("primary_id", int(primary_id)),
|
"sites_web_domain_set_status",
|
||||||
("status", status),
|
("primary_id", int(primary_id)),
|
||||||
))
|
("status", status),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
# ---- helpers ------------------------------------------------------
|
# ---- helpers ------------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -129,11 +538,13 @@ class SitesModule:
|
||||||
return cast(Database, self._c._call("sites_database_get", ("primary_id", int(primary_id))))
|
return cast(Database, self._c._call("sites_database_get", ("primary_id", int(primary_id))))
|
||||||
|
|
||||||
def database_add(self, client_id: int, params: Mapping[str, Any]) -> int:
|
def database_add(self, client_id: int, params: Mapping[str, Any]) -> int:
|
||||||
return int(self._c._call(
|
return int(
|
||||||
"sites_database_add",
|
self._c._call(
|
||||||
("client_id", int(client_id)),
|
"sites_database_add",
|
||||||
("params", dict(params)),
|
("client_id", int(client_id)),
|
||||||
))
|
("params", dict(params)),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def database_delete(self, primary_id: int) -> int:
|
def database_delete(self, primary_id: int) -> int:
|
||||||
return int(self._c._call("sites_database_delete", ("primary_id", int(primary_id))))
|
return int(self._c._call("sites_database_delete", ("primary_id", int(primary_id))))
|
||||||
|
|
@ -142,16 +553,20 @@ class SitesModule:
|
||||||
return cast(DatabaseUser, self._c._call("sites_database_user_get", ("primary_id", int(primary_id))))
|
return cast(DatabaseUser, self._c._call("sites_database_user_get", ("primary_id", int(primary_id))))
|
||||||
|
|
||||||
def database_user_add(self, client_id: int, params: Mapping[str, Any]) -> int:
|
def database_user_add(self, client_id: int, params: Mapping[str, Any]) -> int:
|
||||||
return int(self._c._call(
|
return int(
|
||||||
"sites_database_user_add",
|
self._c._call(
|
||||||
("client_id", int(client_id)),
|
"sites_database_user_add",
|
||||||
("params", dict(params)),
|
("client_id", int(client_id)),
|
||||||
))
|
("params", dict(params)),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def database_user_update(self, client_id: int, primary_id: int, params: Mapping[str, Any]) -> int:
|
def database_user_update(self, client_id: int, primary_id: int, params: Mapping[str, Any]) -> int:
|
||||||
return int(self._c._call(
|
return int(
|
||||||
"sites_database_user_update",
|
self._c._call(
|
||||||
("client_id", int(client_id)),
|
"sites_database_user_update",
|
||||||
("primary_id", int(primary_id)),
|
("client_id", int(client_id)),
|
||||||
("params", dict(params)),
|
("primary_id", int(primary_id)),
|
||||||
))
|
("params", dict(params)),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
|
||||||
86
src/ispconfig/webdav.py
Normal file
86
src/ispconfig/webdav.py
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
"""``webdav.*`` — auto-generated ISPConfig remote-API wrappers.
|
||||||
|
|
||||||
|
This module is produced by ``tools/gen_methods.py`` from the
|
||||||
|
``tools/method_inventory.json`` catalog. Hand-edits go below the
|
||||||
|
``---- HAND-EDIT ONLY BELOW ----`` marker — they survive regeneration.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .client import ISPConfigClient
|
||||||
|
|
||||||
|
|
||||||
|
class WebdavModule:
|
||||||
|
"""Auto-generated module: Webdav.
|
||||||
|
|
||||||
|
All methods below the ``AUTO-GENERATED START`` marker are produced
|
||||||
|
by ``tools/gen_methods.py``. Do not hand-edit that block — changes
|
||||||
|
will be overwritten on the next regeneration. Add helpers and
|
||||||
|
overrides below the ``HAND-EDIT ONLY BELOW`` marker instead.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, client: ISPConfigClient) -> None:
|
||||||
|
self._c = client
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED START (do not hand-edit above this line) ----
|
||||||
|
# Regenerate with: python3 tools/gen_methods.py
|
||||||
|
|
||||||
|
def sites_webdav_user_add(self, client_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_webdav_user_add``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 1043.
|
||||||
|
PHP signature: ``sites_webdav_user_add($session_id, $client_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_webdav_user_add", ("client_id", client_id), ("params", params))
|
||||||
|
|
||||||
|
def sites_webdav_user_delete(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_webdav_user_delete``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 1064.
|
||||||
|
PHP signature: ``sites_webdav_user_delete($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_webdav_user_delete", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_webdav_user_get(self, primary_id: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_webdav_user_get``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 1029.
|
||||||
|
PHP signature: ``sites_webdav_user_get($session_id, $primary_id)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call("sites_webdav_user_get", ("primary_id", primary_id))
|
||||||
|
|
||||||
|
def sites_webdav_user_update(self, client_id: Any, primary_id: Any, params: Any) -> Any:
|
||||||
|
"""
|
||||||
|
Auto-generated wrapper for ``sites_webdav_user_update``.
|
||||||
|
|
||||||
|
Source: ``sites.inc.php`` line 1053.
|
||||||
|
PHP signature: ``sites_webdav_user_update($session_id, $client_id, $primary_id, $params)``.
|
||||||
|
|
||||||
|
AUTO-GENERATED - param shapes may need verification against your
|
||||||
|
ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.
|
||||||
|
"""
|
||||||
|
return self._c._call(
|
||||||
|
"sites_webdav_user_update",
|
||||||
|
("client_id", client_id),
|
||||||
|
("primary_id", primary_id),
|
||||||
|
("params", params),
|
||||||
|
)
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED END ----
|
||||||
|
|
||||||
|
# ---- HAND-EDIT ONLY BELOW ----
|
||||||
|
|
@ -3,6 +3,9 @@
|
||||||
Live-smoke tests read ``ISPCONFIG_TEST_URL``, ``ISPCONFIG_TEST_USER``, and
|
Live-smoke tests read ``ISPCONFIG_TEST_URL``, ``ISPCONFIG_TEST_USER``, and
|
||||||
``ISPCONFIG_TEST_PASS`` from the environment. If any is missing, those tests
|
``ISPCONFIG_TEST_PASS`` from the environment. If any is missing, those tests
|
||||||
are skipped — so the default ``pytest`` run on a laptop never phones home.
|
are skipped — so the default ``pytest`` run on a laptop never phones home.
|
||||||
|
|
||||||
|
Set ``ISPCONFIG_TEST_VERIFY_SSL=0`` for panels with self-signed or
|
||||||
|
mismatched certs.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
@ -19,4 +22,5 @@ def live_creds() -> dict[str, str]:
|
||||||
password = os.environ.get("ISPCONFIG_TEST_PASS")
|
password = os.environ.get("ISPCONFIG_TEST_PASS")
|
||||||
if not (url and user and password):
|
if not (url and user and password):
|
||||||
pytest.skip("live smoke test: set ISPCONFIG_TEST_URL/USER/PASS to enable")
|
pytest.skip("live smoke test: set ISPCONFIG_TEST_URL/USER/PASS to enable")
|
||||||
return {"url": url, "user": user, "password": password}
|
verify = os.environ.get("ISPCONFIG_TEST_VERIFY_SSL", "1")
|
||||||
|
return {"url": url, "user": user, "password": password, "verify": verify}
|
||||||
|
|
|
||||||
|
|
@ -5,23 +5,40 @@ Gated on env vars: ``ISPCONFIG_TEST_URL``, ``ISPCONFIG_TEST_USER``,
|
||||||
|
|
||||||
They are **read-only** — no ``_add`` / ``_update`` / ``_delete`` calls. Safe
|
They are **read-only** — no ``_add`` / ``_update`` / ``_delete`` calls. Safe
|
||||||
to run against production (Rackham).
|
to run against production (Rackham).
|
||||||
|
|
||||||
|
Every new auto-generated module gets at least one read-only call here so we
|
||||||
|
know the wrappers actually wire up against a live panel. Methods that the
|
||||||
|
API user lacks permission for (admin-only, etc.) are documented skips —
|
||||||
|
see the README's "Known admin-only" list.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Iterator
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from ispconfig import ISPConfigClient
|
from ispconfig import ISPConfigClient, NotFoundError, PermissionError
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
def client(live_creds: dict[str, str]) -> ISPConfigClient:
|
def client(live_creds: dict[str, str]) -> Iterator[ISPConfigClient]:
|
||||||
with ISPConfigClient(live_creds["url"], live_creds["user"], live_creds["password"]) as c:
|
verify = live_creds.get("verify", "1") not in ("0", "false", "False")
|
||||||
yield c # type: ignore[misc]
|
with ISPConfigClient(
|
||||||
|
live_creds["url"],
|
||||||
|
live_creds["user"],
|
||||||
|
live_creds["password"],
|
||||||
|
verify_ssl=verify,
|
||||||
|
) as c:
|
||||||
|
yield c
|
||||||
|
|
||||||
|
|
||||||
|
# ---- hand-audited modules (first pass) -----------------------------------
|
||||||
|
|
||||||
|
|
||||||
def test_login_returns_session(live_creds: dict[str, str]) -> None:
|
def test_login_returns_session(live_creds: dict[str, str]) -> None:
|
||||||
c = ISPConfigClient(live_creds["url"], live_creds["user"], live_creds["password"])
|
verify = live_creds.get("verify", "1") not in ("0", "false", "False")
|
||||||
|
c = ISPConfigClient(live_creds["url"], live_creds["user"], live_creds["password"], verify_ssl=verify)
|
||||||
c.login()
|
c.login()
|
||||||
assert c.session_id and len(c.session_id) > 10
|
assert c.session_id and len(c.session_id) > 10
|
||||||
assert c.logout() is True
|
assert c.logout() is True
|
||||||
|
|
@ -45,3 +62,193 @@ def test_mail_users_under_mcbindustrial(client: ISPConfigClient) -> None:
|
||||||
# Don't assert count — just shape. Zero mailboxes is a valid state.
|
# Don't assert count — just shape. Zero mailboxes is a valid state.
|
||||||
for u in users:
|
for u in users:
|
||||||
assert "email" in u
|
assert "email" in u
|
||||||
|
|
||||||
|
|
||||||
|
# ---- auto-generated modules: one read-only probe each -------------------
|
||||||
|
#
|
||||||
|
# These prove the wrappers encode/decode correctly against a real panel.
|
||||||
|
# Each test tolerates the method being restricted to admin (``kayos`` is a
|
||||||
|
# reseller, not an admin) — those skip with a clear reason.
|
||||||
|
|
||||||
|
|
||||||
|
def test_raw_call_list_functions(client: ISPConfigClient) -> None:
|
||||||
|
"""``list_functions`` is the introspection escape hatch — sanity check it."""
|
||||||
|
funcs = client.list_functions()
|
||||||
|
assert "sites_web_domain_get" in funcs
|
||||||
|
assert "mail_user_get" in funcs
|
||||||
|
# 300+ is typical for a modern ISPConfig.
|
||||||
|
assert len(funcs) > 200
|
||||||
|
|
||||||
|
|
||||||
|
def test_raw_call_escape_hatch(client: ISPConfigClient) -> None:
|
||||||
|
"""``raw_call`` must route through the same retry/fault-mapping pipeline."""
|
||||||
|
# ``client_get_all`` is a no-arg read.
|
||||||
|
ids = client.raw_call("client_get_all")
|
||||||
|
assert ids is None or isinstance(ids, (list, dict))
|
||||||
|
|
||||||
|
|
||||||
|
def test_clients_client_get_all(client: ISPConfigClient) -> None:
|
||||||
|
ids = client.clients.get_all()
|
||||||
|
assert isinstance(ids, list)
|
||||||
|
# Don't assert count — panel may be empty of managed clients.
|
||||||
|
|
||||||
|
|
||||||
|
def test_clients_templates_get_all(client: ISPConfigClient) -> None:
|
||||||
|
try:
|
||||||
|
tpls = client.clients.client_templates_get_all()
|
||||||
|
except PermissionError:
|
||||||
|
pytest.skip("client_templates_get_all: admin-only on this panel")
|
||||||
|
assert tpls is None or isinstance(tpls, (list, dict))
|
||||||
|
|
||||||
|
|
||||||
|
def test_server_get_all(client: ISPConfigClient) -> None:
|
||||||
|
try:
|
||||||
|
servers = client.server.server_get_all()
|
||||||
|
except PermissionError:
|
||||||
|
pytest.skip("server_get_all: admin-only on this panel")
|
||||||
|
assert servers is None or isinstance(servers, (list, dict))
|
||||||
|
|
||||||
|
|
||||||
|
def test_server_get_functions(client: ISPConfigClient) -> None:
|
||||||
|
"""Pick the first server id and ask which modules it runs."""
|
||||||
|
try:
|
||||||
|
servers = client.server.server_get_all()
|
||||||
|
except PermissionError:
|
||||||
|
pytest.skip("server_get_all: admin-only on this panel")
|
||||||
|
if not servers:
|
||||||
|
pytest.skip("no servers visible to this API user")
|
||||||
|
# ``server_get_all`` returns a list of server records. Grab the first id.
|
||||||
|
first = servers[0] if isinstance(servers, list) else next(iter(servers.values()))
|
||||||
|
server_id = int(first.get("server_id") if isinstance(first, dict) else first)
|
||||||
|
try:
|
||||||
|
fns = client.server.server_get_functions(server_id)
|
||||||
|
except PermissionError:
|
||||||
|
pytest.skip("server_get_functions: admin-only on this panel")
|
||||||
|
assert fns is None or isinstance(fns, (list, dict))
|
||||||
|
|
||||||
|
|
||||||
|
def test_monitor_jobqueue_count(client: ISPConfigClient) -> None:
|
||||||
|
try:
|
||||||
|
n = client.monitor.monitor_jobqueue_count()
|
||||||
|
except PermissionError:
|
||||||
|
pytest.skip("monitor_jobqueue_count: admin-only on this panel")
|
||||||
|
# Returns an int-ish; ISPConfig may stringify.
|
||||||
|
assert n is None or isinstance(n, (int, str, dict, list))
|
||||||
|
|
||||||
|
|
||||||
|
def test_admin_system_config_get(client: ISPConfigClient) -> None:
|
||||||
|
try:
|
||||||
|
cfg = client.admin.system_config_get("mail")
|
||||||
|
except PermissionError:
|
||||||
|
pytest.skip("system_config_get: admin-only on this panel")
|
||||||
|
assert cfg is None or isinstance(cfg, (dict, list, str))
|
||||||
|
|
||||||
|
|
||||||
|
def test_ftp_user_get_missing(client: ISPConfigClient) -> None:
|
||||||
|
"""Nonexistent primary_id → ``NotFoundError`` via the fault-map path."""
|
||||||
|
try:
|
||||||
|
result = client.ftp.sites_ftp_user_get(999_999_999)
|
||||||
|
except NotFoundError:
|
||||||
|
return # expected
|
||||||
|
except PermissionError:
|
||||||
|
pytest.skip("sites_ftp_user_get: admin-only on this panel")
|
||||||
|
# Some panels return None/empty instead of a fault.
|
||||||
|
assert result in (None, {}, "", [])
|
||||||
|
|
||||||
|
|
||||||
|
def test_shell_user_get_missing(client: ISPConfigClient) -> None:
|
||||||
|
try:
|
||||||
|
result = client.shell.sites_shell_user_get(999_999_999)
|
||||||
|
except NotFoundError:
|
||||||
|
return
|
||||||
|
except PermissionError:
|
||||||
|
pytest.skip("sites_shell_user_get: admin-only on this panel")
|
||||||
|
assert result in (None, {}, "", [])
|
||||||
|
|
||||||
|
|
||||||
|
def test_webdav_user_get_missing(client: ISPConfigClient) -> None:
|
||||||
|
try:
|
||||||
|
result = client.webdav.sites_webdav_user_get(999_999_999)
|
||||||
|
except NotFoundError:
|
||||||
|
return
|
||||||
|
except PermissionError:
|
||||||
|
pytest.skip("sites_webdav_user_get: admin-only on this panel")
|
||||||
|
assert result in (None, {}, "", [])
|
||||||
|
|
||||||
|
|
||||||
|
def test_cron_get_missing(client: ISPConfigClient) -> None:
|
||||||
|
try:
|
||||||
|
result = client.cron.sites_cron_get(999_999_999)
|
||||||
|
except NotFoundError:
|
||||||
|
return
|
||||||
|
except PermissionError:
|
||||||
|
pytest.skip("sites_cron_get: admin-only on this panel")
|
||||||
|
assert result in (None, {}, "", [])
|
||||||
|
|
||||||
|
|
||||||
|
def test_backups_list(client: ISPConfigClient) -> None:
|
||||||
|
"""``sites_web_domain_backup_list`` on a known domain."""
|
||||||
|
try:
|
||||||
|
result = client.backups.sites_web_domain_backup_list(156)
|
||||||
|
except PermissionError:
|
||||||
|
pytest.skip("sites_web_domain_backup_list: admin-only on this panel")
|
||||||
|
except NotFoundError:
|
||||||
|
pytest.skip("no backups configured for domain 156")
|
||||||
|
assert result is None or isinstance(result, (list, dict))
|
||||||
|
|
||||||
|
|
||||||
|
def test_aps_available_packages_list(client: ISPConfigClient) -> None:
|
||||||
|
try:
|
||||||
|
pkgs = client.aps.sites_aps_available_packages_list()
|
||||||
|
except PermissionError:
|
||||||
|
pytest.skip("sites_aps_available_packages_list: admin-only on this panel")
|
||||||
|
except NotFoundError:
|
||||||
|
pytest.skip("APS not initialized on this panel")
|
||||||
|
assert pkgs is None or isinstance(pkgs, (list, dict))
|
||||||
|
|
||||||
|
|
||||||
|
def test_domains_get_all_by_user(client: ISPConfigClient) -> None:
|
||||||
|
"""``domains`` is the (optional) domain-module — may not be installed."""
|
||||||
|
try:
|
||||||
|
# group 1 = admin
|
||||||
|
domains = client.domains.domains_get_all_by_user(1)
|
||||||
|
except PermissionError:
|
||||||
|
pytest.skip("domains_get_all_by_user: admin-only or module disabled")
|
||||||
|
except NotFoundError:
|
||||||
|
pytest.skip("domains module not installed")
|
||||||
|
assert domains is None or isinstance(domains, (list, dict))
|
||||||
|
|
||||||
|
|
||||||
|
def test_openvz_get_free_ip(client: ISPConfigClient) -> None:
|
||||||
|
"""OpenVZ module may not be installed — skip cleanly if so."""
|
||||||
|
try:
|
||||||
|
ip = client.openvz.openvz_get_free_ip()
|
||||||
|
except PermissionError:
|
||||||
|
pytest.skip("openvz_get_free_ip: admin-only or OpenVZ not installed")
|
||||||
|
except NotFoundError:
|
||||||
|
pytest.skip("OpenVZ not installed / no free IPs")
|
||||||
|
assert ip is None or isinstance(ip, (str, dict, list))
|
||||||
|
|
||||||
|
|
||||||
|
def test_misc_quota_get_by_user(client: ISPConfigClient) -> None:
|
||||||
|
"""``quota_get_by_user`` — look up one visible client, query its quota."""
|
||||||
|
try:
|
||||||
|
ids = client.clients.get_all()
|
||||||
|
except PermissionError:
|
||||||
|
pytest.skip("client_get_all: admin-only on this panel")
|
||||||
|
if not ids:
|
||||||
|
pytest.skip("no clients visible to this API user")
|
||||||
|
client_id = int(ids[0])
|
||||||
|
try:
|
||||||
|
group_id = client.clients.get_groupid(client_id)
|
||||||
|
except (PermissionError, NotFoundError):
|
||||||
|
pytest.skip("client_get_groupid: unavailable")
|
||||||
|
if not group_id:
|
||||||
|
pytest.skip("couldn't resolve group id for first visible client")
|
||||||
|
try:
|
||||||
|
quota = client.misc.quota_get_by_user(group_id)
|
||||||
|
except PermissionError:
|
||||||
|
pytest.skip("quota_get_by_user: admin-only on this panel")
|
||||||
|
except NotFoundError:
|
||||||
|
pytest.skip("no quota record for this user")
|
||||||
|
assert quota is None or isinstance(quota, (list, dict))
|
||||||
|
|
|
||||||
|
|
@ -64,27 +64,34 @@ def test_context_manager_auto_login_logout() -> None:
|
||||||
|
|
||||||
|
|
||||||
def test_session_expired_retry() -> None:
|
def test_session_expired_retry() -> None:
|
||||||
t = _FakeTransport([
|
t = _FakeTransport(
|
||||||
"sid-first", # login
|
[
|
||||||
SoapFault("Server", "Session not valid"), # first _call fails
|
"sid-first", # login
|
||||||
"sid-second", # re-login
|
SoapFault("Server", "Session not valid"), # first _call fails
|
||||||
{"domain": "x.com"}, # retry succeeds
|
"sid-second", # re-login
|
||||||
])
|
{"domain": "x.com"}, # retry succeeds
|
||||||
|
]
|
||||||
|
)
|
||||||
c = _make_client(t)
|
c = _make_client(t)
|
||||||
c.login()
|
c.login()
|
||||||
result = c.sites.web_domain_get(1)
|
result = c.sites.web_domain_get(1)
|
||||||
assert result == {"domain": "x.com"}
|
assert result == {"domain": "x.com"}
|
||||||
# 4 transport calls: login, failed get, login, successful get.
|
# 4 transport calls: login, failed get, login, successful get.
|
||||||
assert [call[0] for call in t.calls] == [
|
assert [call[0] for call in t.calls] == [
|
||||||
"login", "sites_web_domain_get", "login", "sites_web_domain_get",
|
"login",
|
||||||
|
"sites_web_domain_get",
|
||||||
|
"login",
|
||||||
|
"sites_web_domain_get",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def test_session_expired_no_retry_when_disabled() -> None:
|
def test_session_expired_no_retry_when_disabled() -> None:
|
||||||
t = _FakeTransport([
|
t = _FakeTransport(
|
||||||
"sid-first",
|
[
|
||||||
SoapFault("Server", "Session expired"),
|
"sid-first",
|
||||||
])
|
SoapFault("Server", "Session expired"),
|
||||||
|
]
|
||||||
|
)
|
||||||
c = ISPConfigClient("http://fake/", "u", "p", max_retries=0)
|
c = ISPConfigClient("http://fake/", "u", "p", max_retries=0)
|
||||||
c._transport = t # type: ignore[assignment]
|
c._transport = t # type: ignore[assignment]
|
||||||
c.login()
|
c.login()
|
||||||
|
|
@ -149,13 +156,13 @@ def test_envelope_encoding_map_and_scalars() -> None:
|
||||||
)
|
)
|
||||||
assert "<session_id" in xml and ">abc<" in xml
|
assert "<session_id" in xml and ">abc<" in xml
|
||||||
assert '<client_id xsi:type="xsd:int">0</client_id>' in xml
|
assert '<client_id xsi:type="xsd:int">0</client_id>' in xml
|
||||||
assert 'ns2:Map' in xml
|
assert "ns2:Map" in xml
|
||||||
assert '<key xsi:type="xsd:string">php</key>' in xml
|
assert '<key xsi:type="xsd:string">php</key>' in xml
|
||||||
assert '<value xsi:type="xsd:string">fast-cgi</value>' in xml
|
assert '<value xsi:type="xsd:string">fast-cgi</value>' in xml
|
||||||
|
|
||||||
|
|
||||||
def test_response_parsing_map() -> None:
|
def test_response_parsing_map() -> None:
|
||||||
body = b'''<?xml version="1.0"?>
|
body = b"""<?xml version="1.0"?>
|
||||||
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
|
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
|
||||||
xmlns:ns1="/remote/index.php"
|
xmlns:ns1="/remote/index.php"
|
||||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||||
|
|
@ -169,19 +176,19 @@ def test_response_parsing_map() -> None:
|
||||||
</return>
|
</return>
|
||||||
</ns1:sites_web_domain_getResponse>
|
</ns1:sites_web_domain_getResponse>
|
||||||
</SOAP-ENV:Body>
|
</SOAP-ENV:Body>
|
||||||
</SOAP-ENV:Envelope>'''
|
</SOAP-ENV:Envelope>"""
|
||||||
result = SoapTransport._parse_response("sites_web_domain_get", body)
|
result = SoapTransport._parse_response("sites_web_domain_get", body)
|
||||||
assert result == {"domain": "mcb.com", "active": "y"}
|
assert result == {"domain": "mcb.com", "active": "y"}
|
||||||
|
|
||||||
|
|
||||||
def test_response_parsing_fault() -> None:
|
def test_response_parsing_fault() -> None:
|
||||||
body = b'''<?xml version="1.0"?>
|
body = b"""<?xml version="1.0"?>
|
||||||
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
|
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
|
||||||
<SOAP-ENV:Body><SOAP-ENV:Fault>
|
<SOAP-ENV:Body><SOAP-ENV:Fault>
|
||||||
<faultcode>SOAP-ENV:Server</faultcode>
|
<faultcode>SOAP-ENV:Server</faultcode>
|
||||||
<faultstring>Login failed.</faultstring>
|
<faultstring>Login failed.</faultstring>
|
||||||
</SOAP-ENV:Fault></SOAP-ENV:Body>
|
</SOAP-ENV:Fault></SOAP-ENV:Body>
|
||||||
</SOAP-ENV:Envelope>'''
|
</SOAP-ENV:Envelope>"""
|
||||||
with pytest.raises(SoapFault) as excinfo:
|
with pytest.raises(SoapFault) as excinfo:
|
||||||
SoapTransport._parse_response("login", body)
|
SoapTransport._parse_response("login", body)
|
||||||
assert "Login failed" in excinfo.value.faultstring
|
assert "Login failed" in excinfo.value.faultstring
|
||||||
|
|
|
||||||
195
tools/extract_inventory.py
Normal file
195
tools/extract_inventory.py
Normal file
|
|
@ -0,0 +1,195 @@
|
||||||
|
"""Extract ISPConfig remote method inventory from PHP sources.
|
||||||
|
|
||||||
|
Reads every ``remote.d/*.inc.php`` plus ``remoting.inc.php`` and dumps a
|
||||||
|
structured inventory to ``tools/method_inventory.json``. Parses ``public
|
||||||
|
function foo($session_id, $bar)`` declarations; scans the preceding lines
|
||||||
|
for a PHPDoc block to pull param types and descriptions.
|
||||||
|
|
||||||
|
This is the generator's input and a diff target. Checking it in makes
|
||||||
|
ISPConfig-upgrade deltas trivially visible in git.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
# (session_id, ...) for most methods; (username, password) for login.
|
||||||
|
# ISPConfig sigs look like ``public function foo($session_id, $params = array())``
|
||||||
|
# — the ``array()`` default means we need to match balanced parens, not
|
||||||
|
# ``[^)]*``, or we'll truncate the signature at the first close-paren. We
|
||||||
|
# also tolerate the opening ``{`` on its own line.
|
||||||
|
_METHOD_RE = re.compile(
|
||||||
|
r"^\s*public\s+function\s+(?P<name>\w+)\s*"
|
||||||
|
r"\((?P<params>(?:[^()]|\([^)]*\))*)\)\s*(?:\n\s*)?\{",
|
||||||
|
re.MULTILINE,
|
||||||
|
)
|
||||||
|
_PARAM_RE = re.compile(r"\$(\w+)(?:\s*=\s*([^,]+))?")
|
||||||
|
|
||||||
|
# Map file basename -> module grouping (for context only; generator re-groups
|
||||||
|
# by method-name prefix, not by file).
|
||||||
|
_FILE_CLASS_MAP = {
|
||||||
|
"sites.inc.php": "sites",
|
||||||
|
"dns.inc.php": "dns",
|
||||||
|
"mail.inc.php": "mail",
|
||||||
|
"client.inc.php": "client",
|
||||||
|
"server.inc.php": "server",
|
||||||
|
"monitor.inc.php": "monitor",
|
||||||
|
"admin.inc.php": "admin",
|
||||||
|
"aps.inc.php": "aps",
|
||||||
|
"domains.inc.php": "domains",
|
||||||
|
"openvz.inc.php": "openvz",
|
||||||
|
"remoting.inc.php": "core",
|
||||||
|
}
|
||||||
|
|
||||||
|
# Methods declared on the base ``remoting`` class that aren't "API methods"
|
||||||
|
# per se — they're internal helpers or lifecycle hooks. We want ``login``,
|
||||||
|
# ``logout``, and the two ``*_functions`` introspection calls; skip the rest.
|
||||||
|
_CORE_WHITELIST = {
|
||||||
|
"login",
|
||||||
|
"logout",
|
||||||
|
"get_function_list",
|
||||||
|
"get_session_token",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _find_docblock(lines: list[str], line_no: int) -> str | None:
|
||||||
|
"""Walk backwards from ``line_no`` looking for the closest ``*/`` and
|
||||||
|
return the enclosing ``/** ... */`` block as raw text, if any."""
|
||||||
|
end = None
|
||||||
|
for i in range(line_no - 1, max(-1, line_no - 60), -1):
|
||||||
|
stripped = lines[i].strip()
|
||||||
|
if not stripped:
|
||||||
|
continue
|
||||||
|
if stripped.endswith("*/"):
|
||||||
|
end = i
|
||||||
|
break
|
||||||
|
# Non-comment, non-blank: no docblock for this method.
|
||||||
|
if not stripped.startswith("*") and not stripped.startswith("/*"):
|
||||||
|
return None
|
||||||
|
if end is None:
|
||||||
|
return None
|
||||||
|
for j in range(end, max(-1, end - 80), -1):
|
||||||
|
if lines[j].lstrip().startswith("/**") or lines[j].lstrip().startswith("/*"):
|
||||||
|
return "\n".join(lines[j : end + 1])
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_params(raw: str) -> list[dict[str, Any]]:
|
||||||
|
"""Extract ``$name`` and optional default from a PHP param list."""
|
||||||
|
out: list[dict[str, Any]] = []
|
||||||
|
for m in _PARAM_RE.finditer(raw):
|
||||||
|
name = m.group(1)
|
||||||
|
default = m.group(2).strip() if m.group(2) else None
|
||||||
|
out.append({"name": name, "default": default})
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_docblock(doc: str | None) -> dict[str, Any]:
|
||||||
|
if not doc:
|
||||||
|
return {"summary": None, "params": [], "return": None}
|
||||||
|
summary_lines: list[str] = []
|
||||||
|
params: list[dict[str, str]] = []
|
||||||
|
ret = None
|
||||||
|
for line in doc.splitlines():
|
||||||
|
text = line.strip()
|
||||||
|
if text.startswith("/**") or text.startswith("/*") or text == "*/":
|
||||||
|
continue
|
||||||
|
if text.startswith("*"):
|
||||||
|
text = text[1:].lstrip()
|
||||||
|
if not text:
|
||||||
|
continue
|
||||||
|
if text.startswith("@param"):
|
||||||
|
# @param int $foo description
|
||||||
|
m = re.match(r"@param\s+(\S+)\s+\$?(\w+)?\s*(.*)", text)
|
||||||
|
if m:
|
||||||
|
params.append(
|
||||||
|
{
|
||||||
|
"type": m.group(1),
|
||||||
|
"name": m.group(2) or "",
|
||||||
|
"desc": m.group(3),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
elif text.startswith("@return"):
|
||||||
|
m = re.match(r"@return\s+(\S+)\s*(.*)", text)
|
||||||
|
if m:
|
||||||
|
ret = {"type": m.group(1), "desc": m.group(2)}
|
||||||
|
elif text.startswith("@"):
|
||||||
|
# Other tags (@author, @throws, etc.) ignored.
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
summary_lines.append(text)
|
||||||
|
return {
|
||||||
|
"summary": " ".join(summary_lines).strip() or None,
|
||||||
|
"params": params,
|
||||||
|
"return": ret,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def extract_file(path: Path) -> list[dict[str, Any]]:
|
||||||
|
src = path.read_text(encoding="utf-8", errors="replace")
|
||||||
|
lines = src.splitlines()
|
||||||
|
out: list[dict[str, Any]] = []
|
||||||
|
for m in _METHOD_RE.finditer(src):
|
||||||
|
name = m.group("name")
|
||||||
|
params_raw = m.group("params")
|
||||||
|
line_no = src[: m.start()].count("\n")
|
||||||
|
# Parse params. Skip the leading $session_id where present (that's
|
||||||
|
# the SDK's job to add) — keep it in the raw list so docstrings can
|
||||||
|
# reflect reality, but flag it.
|
||||||
|
parsed_params = _parse_params(params_raw)
|
||||||
|
doc = _find_docblock(lines, line_no)
|
||||||
|
docinfo = _parse_docblock(doc)
|
||||||
|
out.append(
|
||||||
|
{
|
||||||
|
"method": name,
|
||||||
|
"file": path.name,
|
||||||
|
"line": line_no + 1,
|
||||||
|
"raw_signature": f"{name}({params_raw.strip()})",
|
||||||
|
"params": parsed_params,
|
||||||
|
"doc": docinfo,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def main(src_dir: str, out_path: str) -> None:
|
||||||
|
root = Path(src_dir)
|
||||||
|
records: list[dict[str, Any]] = []
|
||||||
|
for php in sorted(root.glob("*.inc.php")):
|
||||||
|
for rec in extract_file(php):
|
||||||
|
method = rec["method"]
|
||||||
|
# remoting.inc.php holds login/logout + internal helpers.
|
||||||
|
if php.name == "remoting.inc.php" and method not in _CORE_WHITELIST:
|
||||||
|
continue
|
||||||
|
rec["source_class"] = _FILE_CLASS_MAP.get(php.name, "unknown")
|
||||||
|
records.append(rec)
|
||||||
|
# De-dupe by method name (some methods live in multiple files via
|
||||||
|
# inheritance — take the remote.d/ version).
|
||||||
|
seen: dict[str, dict[str, Any]] = {}
|
||||||
|
for rec in records:
|
||||||
|
if rec["method"] not in seen or rec["file"] != "remoting.inc.php":
|
||||||
|
seen[rec["method"]] = rec
|
||||||
|
records = sorted(seen.values(), key=lambda r: (r["source_class"], r["method"]))
|
||||||
|
Path(out_path).parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
Path(out_path).write_text(json.dumps(records, indent=2) + "\n", encoding="utf-8")
|
||||||
|
# Quick stats to stderr so CI logs show what we got.
|
||||||
|
by_class: dict[str, int] = {}
|
||||||
|
for rec in records:
|
||||||
|
by_class[rec["source_class"]] = by_class.get(rec["source_class"], 0) + 1
|
||||||
|
print(f"extracted {len(records)} methods", file=sys.stderr)
|
||||||
|
for cls, n in sorted(by_class.items()):
|
||||||
|
print(f" {cls:<10} {n}", file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
src = sys.argv[1] if len(sys.argv) > 1 else os.environ.get("ISPCONFIG_SRC", "")
|
||||||
|
out = sys.argv[2] if len(sys.argv) > 2 else "tools/method_inventory.json"
|
||||||
|
if not src:
|
||||||
|
print("usage: extract_inventory.py <php-src-dir> [out.json]", file=sys.stderr)
|
||||||
|
sys.exit(2)
|
||||||
|
main(src, out)
|
||||||
446
tools/gen_methods.py
Normal file
446
tools/gen_methods.py
Normal file
|
|
@ -0,0 +1,446 @@
|
||||||
|
"""Generate Python wrappers from the ISPConfig method inventory.
|
||||||
|
|
||||||
|
Reads ``tools/method_inventory.json`` and emits/updates one module per
|
||||||
|
functional area under ``src/ispconfig/``. Each module has two clearly-marked
|
||||||
|
sections:
|
||||||
|
|
||||||
|
# ---- AUTO-GENERATED START (do not hand-edit above this line) ----
|
||||||
|
... wrappers ...
|
||||||
|
# ---- AUTO-GENERATED END ----
|
||||||
|
# ---- HAND-EDIT ONLY BELOW ----
|
||||||
|
... helpers, convenience methods, etc ...
|
||||||
|
|
||||||
|
Re-running the generator replaces only the auto block; hand-edits below
|
||||||
|
the delimiter are preserved. Hand-audited helpers already in the tree
|
||||||
|
(enable_php, a_add with fix_type_bug, user_get with filter-dict
|
||||||
|
normalization, etc.) live below the delimiter and are untouched.
|
||||||
|
|
||||||
|
If an auto-generated method name collides with a hand-audited one
|
||||||
|
(detected by scanning the hand-edit block for ``def <name>(``), the
|
||||||
|
generator skips the auto wrapper — the hand version wins.
|
||||||
|
|
||||||
|
Re-run flow::
|
||||||
|
|
||||||
|
python3 tools/extract_inventory.py <php-src> tools/method_inventory.json
|
||||||
|
python3 tools/gen_methods.py
|
||||||
|
ruff format src/ tools/
|
||||||
|
git diff --stat
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parent.parent
|
||||||
|
INVENTORY = ROOT / "tools" / "method_inventory.json"
|
||||||
|
SRC = ROOT / "src" / "ispconfig"
|
||||||
|
|
||||||
|
AUTO_START = "# ---- AUTO-GENERATED START (do not hand-edit above this line) ----"
|
||||||
|
AUTO_END = "# ---- AUTO-GENERATED END ----"
|
||||||
|
HAND_MARKER = "# ---- HAND-EDIT ONLY BELOW ----"
|
||||||
|
|
||||||
|
# Routing: method-name prefix -> (module filename, class name, method-name
|
||||||
|
# stripping rule). The stripping rule strips a prefix from the Python method
|
||||||
|
# name when we can keep it; we don't, for auto-generated wrappers, so the
|
||||||
|
# generator emits ``method_foo_bar`` as-is. (Hand-audited helpers strip the
|
||||||
|
# prefix for ergonomics — kept below the delimiter.)
|
||||||
|
#
|
||||||
|
# Order matters: first match wins. Longer prefixes first.
|
||||||
|
_ROUTES: list[tuple[str, str, str]] = [
|
||||||
|
# sites.*
|
||||||
|
("sites_web_vhost_aliasdomain_", "sites.py", "SitesModule"),
|
||||||
|
("sites_web_vhost_subdomain_", "sites.py", "SitesModule"),
|
||||||
|
("sites_web_aliasdomain_", "sites.py", "SitesModule"),
|
||||||
|
("sites_web_subdomain_", "sites.py", "SitesModule"),
|
||||||
|
("sites_web_domain_backup", "backups.py", "BackupsModule"),
|
||||||
|
("sites_web_domain_", "sites.py", "SitesModule"),
|
||||||
|
("sites_web_folder_user_", "sites.py", "SitesModule"),
|
||||||
|
("sites_web_folder_", "sites.py", "SitesModule"),
|
||||||
|
("sites_database_user_", "databases.py", "DatabasesModule"),
|
||||||
|
("sites_database_", "databases.py", "DatabasesModule"),
|
||||||
|
("sites_ftp_user_", "ftp.py", "FtpModule"),
|
||||||
|
("sites_shell_user_", "shell.py", "ShellModule"),
|
||||||
|
("sites_cron_", "cron.py", "CronModule"),
|
||||||
|
("sites_webdav_user_", "webdav.py", "WebdavModule"),
|
||||||
|
("sites_aps_", "aps.py", "ApsModule"),
|
||||||
|
("client_", "clients.py", "ClientsModule"),
|
||||||
|
("mail_", "mail.py", "MailModule"),
|
||||||
|
("mailquota_", "mail.py", "MailModule"),
|
||||||
|
("dns_", "dns.py", "DnsModule"),
|
||||||
|
("server_", "server.py", "ServerModule"),
|
||||||
|
("monitor_", "monitor.py", "MonitorModule"),
|
||||||
|
("domains_", "domains.py", "DomainsModule"),
|
||||||
|
("openvz_", "openvz.py", "OpenvzModule"),
|
||||||
|
# admin / misc buckets
|
||||||
|
("sys_datalog_", "admin.py", "AdminModule"),
|
||||||
|
("system_config_", "admin.py", "AdminModule"),
|
||||||
|
("config_value_", "admin.py", "AdminModule"),
|
||||||
|
("update_record_permissions", "admin.py", "AdminModule"),
|
||||||
|
# quotas and misc helpers from sites.inc.php that don't match the
|
||||||
|
# `sites_*` prefix
|
||||||
|
("quota_get_by_user", "misc.py", "MiscModule"),
|
||||||
|
("databasequota_get_by_user", "misc.py", "MiscModule"),
|
||||||
|
("ftptrafficquota_data", "misc.py", "MiscModule"),
|
||||||
|
("trafficquota_get_by_user", "misc.py", "MiscModule"),
|
||||||
|
("client_get_sites_by_user", "misc.py", "MiscModule"),
|
||||||
|
]
|
||||||
|
|
||||||
|
# Modules that already exist in the tree with a hand-audited class. For
|
||||||
|
# these, we append the auto block to an existing class body rather than
|
||||||
|
# writing a fresh module.
|
||||||
|
_PREEXISTING = {
|
||||||
|
"sites.py": "SitesModule",
|
||||||
|
"dns.py": "DnsModule",
|
||||||
|
"mail.py": "MailModule",
|
||||||
|
"databases.py": "DatabasesModule",
|
||||||
|
"clients.py": "ClientsModule",
|
||||||
|
}
|
||||||
|
|
||||||
|
# Methods we skip at generation time: ``login`` and ``logout`` are already
|
||||||
|
# on the top-level client, and ``get_function_list`` is a no-arg
|
||||||
|
# introspection call we expose via ``ISPConfigClient.list_functions()``.
|
||||||
|
_SKIP_METHODS = {"login", "logout", "get_function_list"}
|
||||||
|
|
||||||
|
|
||||||
|
def route(method: str) -> tuple[str, str] | None:
|
||||||
|
for prefix, fname, cls in _ROUTES:
|
||||||
|
if method == prefix or method.startswith(prefix):
|
||||||
|
return fname, cls
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _py_method_name(method: str, prefix: str) -> str:
|
||||||
|
"""Strip the routed prefix from a method name if it's safe to.
|
||||||
|
|
||||||
|
For the auto-generated wrappers we keep the full PHP method name as
|
||||||
|
the Python method name. This is verbose but unambiguous — and matches
|
||||||
|
``raw_call`` semantics so you can grep for the exact PHP string.
|
||||||
|
|
||||||
|
Hand-audited helpers may provide shorter names; they live below the
|
||||||
|
delimiter and take precedence.
|
||||||
|
"""
|
||||||
|
return method # keep the full PHP name; stripping invites collisions
|
||||||
|
|
||||||
|
|
||||||
|
def _docstring(rec: dict[str, Any]) -> list[str]:
|
||||||
|
"""Return docstring lines, indented with 8 spaces (method-body level)."""
|
||||||
|
indent = " "
|
||||||
|
lines = [f'{indent}"""']
|
||||||
|
summary = rec["doc"].get("summary") or f"Auto-generated wrapper for ``{rec['method']}``."
|
||||||
|
# Escape embedded triple quotes defensively.
|
||||||
|
summary = summary.replace('"""', "'''")
|
||||||
|
lines.append(f"{indent}{summary}")
|
||||||
|
lines.append("")
|
||||||
|
lines.append(f"{indent}Source: ``{rec['file']}`` line {rec['line']}.")
|
||||||
|
sig_params = [p["name"] for p in rec["params"] if p["name"] != "session_id"]
|
||||||
|
if sig_params:
|
||||||
|
lines.append(f"{indent}PHP signature: ``{rec['raw_signature']}``.")
|
||||||
|
if rec["doc"]["params"]:
|
||||||
|
lines.append("")
|
||||||
|
lines.append(f"{indent}Params (from PHPDoc):")
|
||||||
|
for p in rec["doc"]["params"]:
|
||||||
|
pname = p.get("name") or "?"
|
||||||
|
if pname == "session_id":
|
||||||
|
continue
|
||||||
|
ptype = p.get("type", "?")
|
||||||
|
desc = (p.get("desc") or "").replace('"""', "'''")
|
||||||
|
if desc:
|
||||||
|
lines.append(f"{indent} {pname} ({ptype}): {desc}")
|
||||||
|
else:
|
||||||
|
lines.append(f"{indent} {pname} ({ptype})")
|
||||||
|
if rec["doc"].get("return"):
|
||||||
|
lines.append("")
|
||||||
|
ret_type = rec["doc"]["return"].get("type", "Any")
|
||||||
|
ret_desc = (rec["doc"]["return"].get("desc") or "").replace('"""', "'''")
|
||||||
|
suffix = f" - {ret_desc}" if ret_desc else ""
|
||||||
|
lines.append(f"{indent}Returns: {ret_type}{suffix}")
|
||||||
|
lines.append("")
|
||||||
|
lines.append(f"{indent}AUTO-GENERATED - param shapes may need verification against your")
|
||||||
|
lines.append(f"{indent}ISPConfig version. File issues at Sulkta-Coop/ispconfig-py.")
|
||||||
|
lines.append(f'{indent}"""')
|
||||||
|
return lines
|
||||||
|
|
||||||
|
|
||||||
|
_PHP_TYPE_MAP = {
|
||||||
|
"int": "int",
|
||||||
|
"integer": "int",
|
||||||
|
"string": "str",
|
||||||
|
"bool": "bool",
|
||||||
|
"boolean": "bool",
|
||||||
|
"array": "dict[str, Any] | list[Any]",
|
||||||
|
"mixed": "Any",
|
||||||
|
"float": "float",
|
||||||
|
"double": "float",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _py_param_type(phpdoc_params: list[dict[str, str]], name: str) -> str:
|
||||||
|
for p in phpdoc_params:
|
||||||
|
if p.get("name") == name:
|
||||||
|
t = (p.get("type") or "").strip().lower().split("|")[0]
|
||||||
|
return _PHP_TYPE_MAP.get(t, "Any")
|
||||||
|
return "Any"
|
||||||
|
|
||||||
|
|
||||||
|
def _emit_method(rec: dict[str, Any]) -> list[str]:
|
||||||
|
method = rec["method"]
|
||||||
|
# Parameters after session_id.
|
||||||
|
params = [p for p in rec["params"] if p["name"] != "session_id"]
|
||||||
|
sig_parts = ["self"]
|
||||||
|
arg_encodes: list[str] = []
|
||||||
|
for p in params:
|
||||||
|
py_type = _py_param_type(rec["doc"]["params"], p["name"])
|
||||||
|
default = p["default"]
|
||||||
|
if default is not None:
|
||||||
|
# PHP defaults are best-effort translated.
|
||||||
|
default_py = _translate_php_default(default)
|
||||||
|
# PEP 484: a None default needs ``| None`` on the annotation.
|
||||||
|
# Any already includes None, so no change needed for Any.
|
||||||
|
if default_py == "None" and py_type not in ("Any", "dict[str, Any] | list[Any]"):
|
||||||
|
py_type = f"{py_type} | None"
|
||||||
|
sig_parts.append(f"{p['name']}: {py_type} = {default_py}")
|
||||||
|
else:
|
||||||
|
sig_parts.append(f"{p['name']}: {py_type}")
|
||||||
|
arg_encodes.append(f'("{p["name"]}", {p["name"]})')
|
||||||
|
signature = ", ".join(sig_parts)
|
||||||
|
lines: list[str] = []
|
||||||
|
lines.append(f" def {method}({signature}) -> Any:")
|
||||||
|
lines.extend(_docstring(rec))
|
||||||
|
if arg_encodes:
|
||||||
|
args_str = ", ".join(arg_encodes)
|
||||||
|
lines.append(f' return self._c._call("{method}", {args_str})')
|
||||||
|
else:
|
||||||
|
lines.append(f' return self._c._call("{method}")')
|
||||||
|
lines.append("")
|
||||||
|
return lines
|
||||||
|
|
||||||
|
|
||||||
|
def _translate_php_default(value: str) -> str:
|
||||||
|
v = value.strip()
|
||||||
|
low = v.lower()
|
||||||
|
if low in ("null",):
|
||||||
|
return "None"
|
||||||
|
if low == "true":
|
||||||
|
return "True"
|
||||||
|
if low == "false":
|
||||||
|
return "False"
|
||||||
|
if low in ("array()", "[]"):
|
||||||
|
return "None" # PHP empty-array default -> None in Python signature
|
||||||
|
# Numeric literals pass through.
|
||||||
|
if re.match(r"^-?\d+(\.\d+)?$", v):
|
||||||
|
return v
|
||||||
|
# Quoted strings.
|
||||||
|
if (v.startswith("'") and v.endswith("'")) or (v.startswith('"') and v.endswith('"')):
|
||||||
|
inner = v[1:-1]
|
||||||
|
return '"' + inner.replace("\\", "\\\\").replace('"', '\\"') + '"'
|
||||||
|
# Unknown → fall back to None (safest default for optional params).
|
||||||
|
return "None"
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
# Module file handling
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
def _module_header(fname: str, cls: str) -> str:
|
||||||
|
"""Stock module header for NEW module files (not preexisting)."""
|
||||||
|
stem = fname.replace(".py", "")
|
||||||
|
mod_title = stem.replace("_", " ").title()
|
||||||
|
return (
|
||||||
|
f'"""``{stem}.*`` — auto-generated ISPConfig remote-API wrappers.\n\n'
|
||||||
|
f"This module is produced by ``tools/gen_methods.py`` from the\n"
|
||||||
|
f"``tools/method_inventory.json`` catalog. Hand-edits go below the\n"
|
||||||
|
f"``{HAND_MARKER.strip('# ')}`` marker — they survive regeneration.\n"
|
||||||
|
f'"""\n\n'
|
||||||
|
f"from __future__ import annotations\n\n"
|
||||||
|
f"from typing import TYPE_CHECKING, Any\n\n"
|
||||||
|
f"if TYPE_CHECKING:\n"
|
||||||
|
f" from .client import ISPConfigClient\n\n\n"
|
||||||
|
f"class {cls}:\n"
|
||||||
|
f' """Auto-generated module: {mod_title}.\n\n'
|
||||||
|
f" All methods below the ``AUTO-GENERATED START`` marker are produced\n"
|
||||||
|
f" by ``tools/gen_methods.py``. Do not hand-edit that block — changes\n"
|
||||||
|
f" will be overwritten on the next regeneration. Add helpers and\n"
|
||||||
|
f" overrides below the ``HAND-EDIT ONLY BELOW`` marker instead.\n"
|
||||||
|
f' """\n\n'
|
||||||
|
f" def __init__(self, client: ISPConfigClient) -> None:\n"
|
||||||
|
f" self._c = client\n\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _find_existing_auto_block(text: str) -> tuple[int, int] | None:
|
||||||
|
"""Return (start_line_idx, end_line_idx) of the existing auto block, if any."""
|
||||||
|
lines = text.splitlines()
|
||||||
|
start = end = None
|
||||||
|
for i, line in enumerate(lines):
|
||||||
|
if AUTO_START in line:
|
||||||
|
start = i
|
||||||
|
if AUTO_END in line and start is not None:
|
||||||
|
end = i
|
||||||
|
break
|
||||||
|
if start is None or end is None:
|
||||||
|
return None
|
||||||
|
return start, end
|
||||||
|
|
||||||
|
|
||||||
|
def _find_class_body_insertion(text: str, cls: str) -> int | None:
|
||||||
|
"""Find the line index of the first blank line AFTER the class's __init__
|
||||||
|
(a sensible spot to inject the auto block in a preexisting module).
|
||||||
|
"""
|
||||||
|
lines = text.splitlines()
|
||||||
|
in_class = False
|
||||||
|
saw_init = False
|
||||||
|
for i, line in enumerate(lines):
|
||||||
|
if re.match(rf"class\s+{cls}\b", line):
|
||||||
|
in_class = True
|
||||||
|
continue
|
||||||
|
if in_class and "def __init__" in line:
|
||||||
|
saw_init = True
|
||||||
|
if saw_init and line.strip() == "":
|
||||||
|
return i + 1
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _extract_hand_method_names(text: str, auto_end: int | None) -> set[str]:
|
||||||
|
"""Scan everything AFTER the auto block for ``def <name>(`` so the
|
||||||
|
generator can skip methods a hand-audited helper already claims.
|
||||||
|
"""
|
||||||
|
lines = text.splitlines()
|
||||||
|
start = (auto_end + 1) if auto_end is not None else 0
|
||||||
|
names: set[str] = set()
|
||||||
|
for line in lines[start:]:
|
||||||
|
m = re.match(r"\s+def\s+(\w+)\s*\(", line)
|
||||||
|
if m:
|
||||||
|
names.add(m.group(1))
|
||||||
|
return names
|
||||||
|
|
||||||
|
|
||||||
|
def _render_auto_block(records: list[dict[str, Any]], hand_names: set[str]) -> list[str]:
|
||||||
|
lines: list[str] = []
|
||||||
|
lines.append(f" {AUTO_START}")
|
||||||
|
lines.append(" # Regenerate with: python3 tools/gen_methods.py")
|
||||||
|
lines.append("")
|
||||||
|
emitted_names: set[str] = set()
|
||||||
|
for rec in sorted(records, key=lambda r: r["method"]):
|
||||||
|
if rec["method"] in hand_names:
|
||||||
|
lines.append(f" # skipped {rec['method']}: hand-audited helper below takes precedence")
|
||||||
|
lines.append("")
|
||||||
|
continue
|
||||||
|
if rec["method"] in emitted_names:
|
||||||
|
continue
|
||||||
|
emitted_names.add(rec["method"])
|
||||||
|
lines.extend(_emit_method(rec))
|
||||||
|
lines.append(f" {AUTO_END}")
|
||||||
|
lines.append("")
|
||||||
|
lines.append(f" {HAND_MARKER}")
|
||||||
|
lines.append("")
|
||||||
|
return lines
|
||||||
|
|
||||||
|
|
||||||
|
def _ensure_any_imported(text: str) -> str:
|
||||||
|
"""Make sure ``Any`` is imported from ``typing`` — auto-generated wrappers
|
||||||
|
always need it. Leaves other imports untouched; idempotent.
|
||||||
|
"""
|
||||||
|
if re.search(r"^from\s+typing\s+import[^\n]*\bAny\b", text, re.MULTILINE):
|
||||||
|
return text
|
||||||
|
m = re.search(r"^(from\s+typing\s+import\s+)([^\n]+)$", text, re.MULTILINE)
|
||||||
|
if m:
|
||||||
|
current = m.group(2)
|
||||||
|
# Append ``Any``; keep symbols sorted lexically for stable diffs.
|
||||||
|
symbols = sorted({s.strip() for s in current.split(",")} | {"Any"})
|
||||||
|
new_line = m.group(1) + ", ".join(symbols)
|
||||||
|
return text[: m.start()] + new_line + text[m.end() :]
|
||||||
|
# No ``from typing import`` at all — add one after ``from __future__``.
|
||||||
|
fut = re.search(r"^from\s+__future__\s+import[^\n]*$", text, re.MULTILINE)
|
||||||
|
if fut:
|
||||||
|
insertion = fut.end()
|
||||||
|
return text[:insertion] + "\n\nfrom typing import Any" + text[insertion:]
|
||||||
|
# Last resort: prepend.
|
||||||
|
return "from typing import Any\n\n" + text
|
||||||
|
|
||||||
|
|
||||||
|
def _update_existing_module(path: Path, cls: str, records: list[dict[str, Any]]) -> None:
|
||||||
|
text = path.read_text(encoding="utf-8")
|
||||||
|
text = _ensure_any_imported(text)
|
||||||
|
block = _find_existing_auto_block(text)
|
||||||
|
if block is None:
|
||||||
|
# First-time injection: find where to insert.
|
||||||
|
lines = text.splitlines()
|
||||||
|
insertion = _find_class_body_insertion(text, cls)
|
||||||
|
if insertion is None:
|
||||||
|
print(f"WARN: couldn't find insertion point in {path}", file=sys.stderr)
|
||||||
|
return
|
||||||
|
hand_names = _extract_hand_method_names(text, auto_end=None)
|
||||||
|
auto_lines = _render_auto_block(records, hand_names)
|
||||||
|
new_lines = lines[:insertion] + auto_lines + lines[insertion:]
|
||||||
|
path.write_text("\n".join(new_lines).rstrip() + "\n", encoding="utf-8")
|
||||||
|
return
|
||||||
|
start, end = block
|
||||||
|
lines = text.splitlines()
|
||||||
|
hand_names = _extract_hand_method_names(text, auto_end=end)
|
||||||
|
auto_lines = _render_auto_block(records, hand_names)
|
||||||
|
# Replace start..end+possible trailing hand-marker line; we also re-emit the
|
||||||
|
# hand marker so we own its exact placement. Consume any blank lines plus
|
||||||
|
# a HAND_MARKER (with optional trailing blank) between AUTO_END and the
|
||||||
|
# first real code below — we'll re-emit the marker ourselves at the end
|
||||||
|
# of ``auto_lines``.
|
||||||
|
after = end + 1
|
||||||
|
while after < len(lines) and lines[after].strip() == "":
|
||||||
|
after += 1
|
||||||
|
if after < len(lines) and HAND_MARKER in lines[after]:
|
||||||
|
after += 1
|
||||||
|
while after < len(lines) and lines[after].strip() == "":
|
||||||
|
after += 1
|
||||||
|
new_lines = lines[:start] + auto_lines + lines[after:]
|
||||||
|
path.write_text("\n".join(new_lines).rstrip() + "\n", encoding="utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
def _write_new_module(path: Path, cls: str, records: list[dict[str, Any]]) -> None:
|
||||||
|
header = _module_header(path.name, cls)
|
||||||
|
auto_lines = _render_auto_block(records, hand_names=set())
|
||||||
|
body = header + "\n".join(auto_lines).rstrip() + "\n"
|
||||||
|
path.write_text(body, encoding="utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
records = json.loads(INVENTORY.read_text(encoding="utf-8"))
|
||||||
|
SRC.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
by_module: dict[tuple[str, str], list[dict[str, Any]]] = {}
|
||||||
|
unrouted: list[str] = []
|
||||||
|
for rec in records:
|
||||||
|
if rec["method"] in _SKIP_METHODS:
|
||||||
|
continue
|
||||||
|
routed = route(rec["method"])
|
||||||
|
if routed is None:
|
||||||
|
unrouted.append(rec["method"])
|
||||||
|
# Default bucket = misc.py
|
||||||
|
routed = ("misc.py", "MiscModule")
|
||||||
|
key = routed
|
||||||
|
by_module.setdefault(key, []).append(rec)
|
||||||
|
|
||||||
|
for (fname, cls), recs in sorted(by_module.items()):
|
||||||
|
path = SRC / fname
|
||||||
|
if path.exists() and fname in _PREEXISTING:
|
||||||
|
_update_existing_module(path, cls, recs)
|
||||||
|
action = "updated"
|
||||||
|
elif path.exists():
|
||||||
|
_update_existing_module(path, cls, recs)
|
||||||
|
action = "refreshed"
|
||||||
|
else:
|
||||||
|
_write_new_module(path, cls, recs)
|
||||||
|
action = "created"
|
||||||
|
print(f"{action:<10} {fname:<16} ({len(recs)} methods)")
|
||||||
|
|
||||||
|
if unrouted:
|
||||||
|
print(f"\nUNROUTED ({len(unrouted)}) — filed under misc.py:", file=sys.stderr)
|
||||||
|
for m in unrouted:
|
||||||
|
print(f" {m}", file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
8284
tools/method_inventory.json
Normal file
8284
tools/method_inventory.json
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue