Skip to content

GLPI Cloud — OVHcloud

OVHcloud provider for the glpicloud plugin. Auth, enumeration and cost.

Requires glpicloud to be installed and active. No tables, menu, rights or settings of its own.

Paths and payload shapes were taken from OVHcloud’s machine-readable schemas (https://api.us.ovhcloud.com/1.0/ and the *.json under it), not from the prose documentation.

Service Scope Products
compute project instances
storage project volumes, object-storage containers, snapshots
network project public IPs, load balancers
containers project Managed Kubernetes clusters, container registries
database project managed database clusters (Postgres, MySQL, Mongo, Kafka, …)
hosting account VPS, dedicated servers
dns account DNS zones

There is no “everything else” bucket. OVH has no endpoint listing an account’s resources irrespective of product, so the inventory is exactly this table. A product with no collector is absent rather than mistyped.

Two structural differences from other providers

Section titled “Two structural differences from other providers”

Scopes. Public Cloud lives under /cloud/project/{id}, while VPS, dedicated servers and DNS zones hang off the account. The provider reports one scope per Public Cloud project plus a synthetic account scope, and each collector knows which it belongs to.

N+1 listing. /vps, /dedicated/server, /kube, /database/service and /loadbalancer return string[], so each item costs a request — more than one cron tick’s budget on a large account. The walk lists once, yields in order and checkpoints a cursor naming the kind, the identifiers and the position. A bare position would be applied to the wrong kind, since one service collects several.

An item that 404s between the list and the fetch is skipped rather than fatal: an abandoned sweep concludes nothing about what disappeared, which is wrong for a resource that really has gone.

An OVH application credential, created at /createToken on your region’s API console, with GET-only rules:

GET /auth/currentCredential
GET /me
GET /cloud/project
GET /cloud/project/*
GET /vps
GET /vps/*
GET /dedicated/server
GET /dedicated/server/*
GET /domain/zone

The restriction is carried by the token, so the plugin cannot issue anything else. Every request it makes is a GET.

The API region is part of the credential rather than a preference — an account lives in exactly one and the others refuse its keys — so it is a dropdown.

Requests are signed with a timestamp and OVH rejects a drifted one as an authentication error, which reads like a wrong secret. The signer takes OVH’s time from the unauthenticated /auth/time once per run and keeps the offset.

/cloud/project/{id}/usage/current for the month in progress (flagged provisional) and /usage/history for closed months.

Attribution uses one path for every product: resourcesUsage[].resources[].components[].resourceId. Anything unattributed becomes a row of its own — matched cost is summed and subtracted from totalPrice.value, and the remainder is stored against the account, so the total in GLPI equals what OVH says the period cost.

Accounts with no Public Cloud project still have cost. Dedicated servers, VPSs and domains are invoiced monthly rather than metered, so cost comes from /me/bill, using each invoice’s detail lines: the domain field is the service name already used as an identifier, and periodStart is the service period rather than the invoice date. Each invoice reconciles the same way. Needs GET /me/bill and GET /me/bill/* on the consumer key.

Object-storage cost currently falls in the unattributed remainder: billing keys buckets by name and region, inventory keys them by id, and matching on a name across regions would be a guess.

Terminal window
tests/run.sh # pure PHP, no GLPI, no network
docker compose -p glpi exec glpi \
php /var/www/glpi/plugins/glpicloudovh/tests/http.php # needs Guzzle, still no network

signature.php pins the request signature to vectors computed independently of this code, and covers the clock it depends on. walk.php covers the N+1 walk: resumption, a deleted item mid-walk, budgets, deadlines, the oversized-cursor fallback. cost.php covers the arithmetic. descriptor.php hands the descriptor to glpicloud’s own registry.

Not verified against a real OVH account.

Terminal window
# from the GLPI root — the directory must be named for the plugin key,
# which is not the repository name
git clone https://github.com/bijstaan/glpi-cloud-ovh.git plugins/glpicloudovh
php bin/console plugin:install -u glpi glpicloudovh
php bin/console plugin:activate glpicloudovh

GPL-3.0-or-later, the same licence as GLPI. The plugin is loaded into GLPI’s process and extends its classes, so it is a derivative work. See LICENSE.