Skip to content

Miran ​

Status: available · package wg-flow-plugin-miran 0.1.0 · provider miran · category cloud.

The plugin reads a Miran client cabinet through the BILLmanager API at https://bill.miran.ru/billmgr. Inventory receives dedicated servers, VDS, domains, virtual hosting, colocation, and IP services. The cabinet login and password stay in the agent YAML.

One source is one cabinet login. The plugin only reads the API: it does not order or change services. It opens a session (func=auth) and sends that id on later calls. The password is posted in the body, not in the URL. The session is tied to the agent IP and lasts about an hour after the last request; the next run logs in again.

If the panel has no function for a product (unknown function), that list is empty and the source still succeeds. Any other list error fails the whole source, so a partial snapshot is not sent. Deleted services (item_status = 4) are omitted, and inventory marks them inactive.

Tickets, payments, licenses, DNS records, and rack energy statistics are not collected in 0.1.0.

Provider docs: API overview, authorization.

Install ​

The agent must be connected to the API.

bash
docker compose exec agent wg-flow-agent plugin install miran
# or
wg-flow-agent plugin install miran

Then the local UI → Connections → miran, or YAML.

What lands in inventory ​

Miran objectresource_typeNotes
Dedicated serverserverfunc=dedic. provider_resource_id = server:{id}. The name is the service domain. Public IPv4 → metadata.primary_ipv4, private addresses → metadata.private_ips. The data center is the region
VDSinstancefunc=vds. instance:{id}. A panel VM name that differs from the domain is stored in metadata.server_name
Domaindomainfunc=domain. provider_resource_id is the domain name (example.net). An expire date of 0000-00-00 is omitted
Virtual hostinghostingfunc=vhost. hosting:{id}
Colocationserverfunc=colocation. colocation:{id}, so it does not collide with a dedicated server. metadata.product = colocation
IP addressnetworkfunc=ip. ip:{id}. metadata.product = additional_ip. Inventory has no separate ip type

BILLmanager service status: 1 ordered → pending, 2 active → active, 3 suspended → stopped, 5 processing → pending. Other codes → unknown.

The cost field is stored as metadata.plan_price and metadata.billing_amount. If the row has no currency code, the plugin stores RUB. The tariff is metadata.plan_name, the OS template is metadata.image, and the end date is metadata.expire_date. The client name and the panel password are not copied into metadata.

Each collect flag can be turned off on its own. A disabled group is absent from the next successful sync, and inventory marks those rows inactive.

Several cabinets mean several sources. provider_account is your label.

YAML ​

yaml
plugins:
  miran:
    enabled: true
    sources:
      - id: cabinet
        provider_account: "miran-main"
        sync_interval_seconds: 300
        api_url: "https://bill.miran.ru/billmgr"
        username: "client"
        password: "…"
        collect_dedicated: true
        collect_vds: true
        collect_domains: true
        collect_hosting: true
        collect_colocation: true
        collect_ips: true

Source fields ​

FieldRequiredDescription
idyesLog key (miran/cabinet)
provider_accountyesCabinet label in inventory
api_urlnoDefault https://bill.miran.ru/billmgr
username, passwordyesbill.miran.ru cabinet login
collect_*noDefault true
sync_interval_secondsnoMinimum 300

Check ​

bash
wg-flow-agent status
wg-flow-agent dry-run

JSON shows provider: miran. Health opens a session and calls func=dashboard.info. The password is not stored in inventory.

Common errors ​

SymptomWhat to check
Invalid username or passwordCabinet login pair. A password with special characters is a separate field, not a user:password string
Session rejectedThe agent IP must be allowed to call the cabinet API. An IP allow-list blocks the session too
Empty server listServices exist on this login and the matching collect_* flag is on. Deleted services (4) are hidden
No domains or hostingThe panel has no such function. That does not fail the source
Access denied on a listThis login cannot call that function. The source does not send a partial snapshot
Duplicates with another pluginA different provider is expected; merge them in the console