ias/infoblox
Laravel package for integrating Infoblox DNS/IPAM into your applications. It wraps the Infoblox WAPI in a clean PHP API for querying and managing networks, IP addresses, DNS records, and related objects, with configuration and Laravel service provider support.
This is not a Laravel package despite the "Laravel-friendly" framing. There is no service provider, no facade, no publishable config — the repository ships a PHP client plus a Symfony bundle (theias/di/infoblox, private GitLab). You will wire it into Laravel yourself. Budget half a day for plumbing, not for reading docs.
Minimal steps:
repositories entry (VCS type, SSH or token auth) and require a pinned commit, not a floating tag:
"repositories": [{"type": "vcs", "url": "[email protected]:theias/di/infoblox.git"}]
Put credentials in COMPOSER_AUTH / CI job tokens — every dev and every CI runner needs access. There is no Private Packagist mirror, so plan for that friction.composer.json first. Check PHP constraint against your runtime, and whether it depends on guzzlehttp/guzzle, symfony/http-client, or a bare PSR-18 client. If it pulls symfony/framework-bundle in require, stop and evaluate a fork before going further.src/ for the client class and credentials DTO, plus the Symfony bundle's services.yaml — that file tells you exactly which constructor args the client expects. Ignore the bundle registration itself; Laravel will never load it.config/infoblox.php (host, WAPI version, username, password, timeouts, verify-tls) and bind the client as a singleton in an InfobloxServiceProvider. Resolve credentials from a secrets manager, not a committed .env.php artisan infoblox:ping that fetches network containers or resolves one record:a. This isolates auth, WAPI version, and TLS in a single cheap step before you touch writes.The single highest-value early check: hit the WAPI version endpoint your grid actually supports and compare it to the /wapi/vX/ path the client hardcodes. A version mismatch surfaces as 400s that look like auth failures and will burn a day.
Adapter first, package second. Define your own interface (NetworkRegistry or InfobloxGateway) with domain verbs — reserveIp($network), createARecord($fqdn, $ip, $ttl), findByFqdn($fqdn) — and an implementation that delegates to the package client. Nothing in business logic imports a WAPI class name. Swap-out becomes a one-class change, and tests fake the interface instead of mocking HTTP.
Service provider shape. Bind the raw client as a singleton (it's stateless and cheap to reuse across a request lifecycle). Do not resolve a new client per call — you'll re-authenticate on every WAPI round-trip.
Provisioning workflow (the common real use case). WAPI has no transactions, so you own compensation logic:
_function=next_available_ip on the container → get an IP.record:a (and record:ptr if your grid doesn't auto-generate)._ref in your DB alongside the resource it belongs to.Testing. Bind a fake implementation of your interface in the container for unit tests. For integration, if the client exposes its underlying HTTP client, swap in Guzzle's MockHandler with recorded WAPI JSON. If it doesn't expose it, point the base URI at a local stub server serving fixtures. There is no community fixture corpus — you write these.
Cache the slow, invalidate on write. Zones, network containers, and DHCP ranges change rarely; cache them with a short TTL. Your cache does not know when the package writes — invalidate explicitly in the adapter's write methods, and never cache next_available_ip.
Bulk work. Iterate with explicit _max_results and paging handling; add your own backoff. Do not assume the package rate-limits for you. For migration-scale jobs, run through a queue with idempotency keys on record names.
php artisan vendor:publish will do nothing. No service provider is registered, so no config or migrations are publishable. Write config by hand.400 Bad Request, easily mistaken for bad credentials. Confirm the client's version against your Grid Master before writing anything.404 for a missing _ref but 400 for an unknown search field, and 401/403 for auth/permission. The package probably throws one generic exception — wrap it in your own InfobloxNotFound, InfobloxAuthError, InfobloxConflict before any retry logic. Safe retries depend on this distinction; blind retries on a create will duplicate DNS records._max_results silently truncates. If the client doesn't page for you, a query that returns 1,000 records looks complete. A drift-detection job that works in dev will silently miss records in production.HandlerStack middleware (or the client's logger if one exists) to log the full request URL, method, and body — but redact the Authorization header. WAPI responses include a text field with useful detail you'll want surfaced in logs._function=..., extensible attributes via _return_fields, _paging) are almost certainly reachable through a generic request()/call() on the client. Wrap it in your adapter; never edit vendor/.composer.lock will record a commit SHA with no tag. After your pilot, fork into your namespace and tag releases so a bad upstream push can't break your build overnight. Assume no upstream support — assign an internal owner.How can I help you explore Laravel packages today?