Skip to content

API Reference Public API Endpoints Availability Endpoints

Jordan edited this page Aug 17, 2026 · 9 revisions

Availability Endpoints

Preserved Qoder snapshot. This deep-dive page is retained so the earlier Wiki work and its source trail are not lost. For the reconciled implementation, Architecture Overview is canonical; references below to retired controllers, listeners, services, or API shapes are historical.

**Referenced Files in This Document** - [routes/api.php](https://github.com/ObsidianNetwork/dynamic-pterodactyl/blob/6b7f83bda6f7c3fe014d52428b31af1638daa6cc/routes/api.php) - [AvailabilityController.php](https://github.com/ObsidianNetwork/dynamic-pterodactyl/blob/6b7f83bda6f7c3fe014d52428b31af1638daa6cc/Http/Controllers/Api/AvailabilityController.php) - [NodeSelectionService.php](https://github.com/ObsidianNetwork/dynamic-pterodactyl/blob/6b7f83bda6f7c3fe014d52428b31af1638daa6cc/Services/NodeSelectionService.php) - [ResourceCalculationService.php](https://github.com/ObsidianNetwork/dynamic-pterodactyl/blob/6b7f83bda6f7c3fe014d52428b31af1638daa6cc/Services/ResourceCalculationService.php) - [EnsureUserIsAdmin.php](https://github.com/ObsidianNetwork/dynamic-pterodactyl/blob/6b7f83bda6f7c3fe014d52428b31af1638daa6cc/Http/Middleware/EnsureUserIsAdmin.php) - [AvailabilityApiTest.php](https://github.com/ObsidianNetwork/dynamic-pterodactyl/blob/6b7f83bda6f7c3fe014d52428b31af1638daa6cc/tests/Feature/AvailabilityApiTest.php) - [DECISIONS.md](https://github.com/ObsidianNetwork/dynamic-pterodactyl/blob/6b7f83bda6f7c3fe014d52428b31af1638daa6cc/DECISIONS.md)

Update Summary

Changes Made

  • Enhanced security section with new test assertions for preventing node-level data exposure
  • Updated endpoint specification to emphasize security boundaries
  • Added comprehensive security testing coverage details
  • Strengthened error handling documentation with security considerations

Table of Contents

  1. Introduction
  2. Project Structure
  3. Core Components
  4. Architecture Overview
  5. Detailed Component Analysis
  6. Security and Data Exposure Prevention
  7. Dependency Analysis
  8. Performance Considerations
  9. Troubleshooting Guide
  10. Conclusion

Introduction

This document specifies the customer-facing availability endpoint that returns aggregate, location-based capacity data for Pterodactyl nodes. It covers authentication, rate limiting, request/response schemas, error handling, performance characteristics, and comprehensive security measures designed to prevent node-level data exposure to customers. The endpoint is designed to answer "what can I get at this location right now?" without exposing node-level internals to customers.

Project Structure

The availability feature spans routes, a controller, and services that call the Pterodactyl API in real time. Customer endpoints are grouped under a single route prefix with shared middleware for session-based authentication and throttling. Security measures ensure that only aggregate data is returned to customers while detailed node information remains admin-only.

graph TB
Client["Customer Client"] --> Routes["API Routes<br/>/api/dynamic-pterodactyl"]
Routes --> MW["Middleware: web, auth, throttle:30,1"]
MW --> Ctrl["AvailabilityController::getByLocation"]
Ctrl --> ResCalc["ResourceCalculationService::getLocationAvailability"]
Ctrl --> NodeSel["NodeSelectionService::getMaxAvailable with preloaded snapshot"]
ResCalc --> Ptero["Pterodactyl API"]
Ctrl --> Security["Security Layer<br/>Data Sanitization"]
Security --> Response["Secure JSON Response<br/>No Node Details"]
Loading

Diagram sources

Section sources

Core Components

  • Route group: Defines the public availability endpoint and applies session-based authentication and rate limiting.
  • Controller: Orchestrates aggregation and returns a simplified response to customers with built-in security sanitization.
  • Services:
    • NodeSelectionService: Computes maximum allocatable resources across a location.
    • ResourceCalculationService: Fetches live node/server data from Pterodactyl and aggregates totals and per-node details (used internally and by admin).

Key responsibilities:

  • Enforce authentication via web session and auth middleware.
  • Throttle requests to protect downstream Pterodactyl API budget.
  • Aggregate per-location maxima for memory, CPU, and disk.
  • Provide a boolean flag indicating whether all three resources have positive availability.
  • Enhanced: Ensure no node-level data leaks to customer responses through comprehensive testing and validation.

Section sources

Architecture Overview

The GET /api/dynamic-pterodactyl/availability/{locationId} flow:

  1. Request enters the route group with web + auth + throttle middleware.
  2. AvailabilityController::getByLocation fetches one location snapshot via ResourceCalculationService.
  3. It passes that same snapshot to NodeSelectionService to read max_available, then computes node_count and resource_capacity booleans without another panel request.
  4. A compact JSON response is returned with only aggregate fields; no node identifiers or internal details are exposed.
  5. Enhanced: Comprehensive test coverage ensures security boundaries are maintained.
sequenceDiagram
participant C as "Client"
participant R as "Routes"
participant M as "Auth + Throttle"
participant A as "AvailabilityController"
participant N as "NodeSelectionService"
participant S as "ResourceCalculationService"
participant P as "Pterodactyl API"
C->>R : GET /api/dynamic-pterodactyl/availability/{locationId}
R->>M : Apply web, auth, throttle : 30,1
M-->>A : Proceed if authenticated and within limit
A->>S : getLocationAvailability(locationId)
S->>P : GET /locations/{id}?include=nodes,servers
P-->>S : Node and server data
S-->>A : Aggregated location data including nodes[]
A->>N : getMaxAvailable(locationId, locationData)
N-->>A : Max available from the same snapshot
A->>A : Security sanitization<br/>Remove node details
A-->>C : {success, data : {location_id, max_memory, max_cpu, max_disk, node_count, has_capacity, resource_capacity}}
Loading

Diagram sources

Detailed Component Analysis

Endpoint Specification: GET /api/dynamic-pterodactyl/availability/{locationId}

  • Path parameter:
    • locationId: integer. Identifies the target Pterodactyl location.
  • Authentication:
    • Requires an active web session and authenticated user via the web and auth middleware applied to the route group.
  • Rate limiting:
    • 30 requests per minute per client identity enforced by the throttle middleware on the route group.
  • Success response schema:
    • success: boolean
    • data: object
      • location_id: integer
      • max_memory: integer (maximum allocatable memory across nodes in the location)
      • max_cpu: integer (maximum allocatable CPU threads across nodes in the location)
      • max_disk: integer (maximum allocatable disk MB across nodes in the location)
      • node_count: integer (number of nodes in the location)
      • has_capacity: boolean (true only when memory, cpu, and disk are all > 0)
      • resource_capacity: object
        • memory: boolean (true if max_memory > 0)
        • cpu: boolean (true if max_cpu > 0)
        • disk: boolean (true if max_disk > 0)
  • Error responses:
    • On exceptions during processing, returns HTTP 500 with success: false and the generic message Failed to fetch availability. Exception details are reported server-side and are not returned to customers.

Request examples

  • Basic request:
    • GET /api/dynamic-pterodactyl/availability/1
    • Headers: Cookie (session), Authorization not required (uses session)
  • Example success response:
    • { "success": true, "data": { "location_id": 1, "max_memory": 16384, "max_cpu": 400, "max_disk": 102400, "node_count": 3, "has_capacity": true, "resource_capacity": { "memory": true, "cpu": true, "disk": true } } }
  • Example partial capacity response:
    • { "success": true, "data": { "location_id": 1, "max_memory": 16384, "max_cpu": 0, "max_disk": 102400, "node_count": 3, "has_capacity": false, "resource_capacity": { "memory": true, "cpu": false, "disk": true } } }

Error handling

  • Invalid or missing locationId:
    • If the location does not exist or cannot be resolved, the controller returns success: false with a generic message and reports the underlying exception server-side.
  • Pterodactyl API failures:
    • Network timeouts, connection errors, or non-2xx responses result in a generic success: false response; upstream details remain in server-side diagnostics.
  • Rate limiting exceeded:
    • Requests beyond 30 per minute receive a standard throttle response from the framework's throttle middleware.

Why node-level details are not exposed

  • Customer-facing endpoints intentionally return only aggregate per-location maxima and counts. Node names, FQDNs, maintenance flags, and per-node capacities are reserved for admin-only access. This reduces information leakage and keeps the customer experience focused on "can I buy here?" rather than infrastructure specifics.
  • Enhanced Security: Comprehensive test coverage ensures that node-level data never leaks to customer responses through automated assertions.

Section sources

Service Layer: Aggregation and Real-Time Data

  • NodeSelectionService::getMaxAvailable
    • Delegates to ResourceCalculationService to obtain location availability and extracts the maximum allocatable values across nodes.
  • ResourceCalculationService::getLocationAvailability
    • Fetches nodes in the specified location and their servers from Pterodactyl.
    • Computes effective capacity per node using overallocation settings and subtracts allocated and pending reservations.
    • Tracks max_available (per-resource maximum across nodes) and total_capacity/total_allocated aggregates.
    • Returns both per-node details (for internal/admin use) and aggregated metrics.
flowchart TD
Start(["getLocationAvailability(locationId)"]) --> FetchNodes["Fetch location with nodes and servers"]
FetchNodes --> ForEachNode{"For each node"}
ForEachNode --> |Yes| CalcNode["Calculate node availability<br/>from servers + reservations"]
CalcNode --> UpdateMax["Update max_available per resource"]
UpdateMax --> UpdateTotals["Accumulate total_capacity and total_allocated"]
UpdateTotals --> ForEachNode
ForEachNode --> |No| ReturnData["Return {location_id, nodes[], max_available, totals}"]
Loading

Diagram sources

Section sources

Middleware and Security

  • Web session and authentication:
    • The route group applies web and auth middleware, ensuring the caller has an active session and is authenticated.
  • Admin-only node detail endpoint:
    • The /availability/{locationId}/nodes endpoint is protected by additional admin middleware and is not part of the customer surface.
  • Throttling:
    • Availability endpoints are limited to 30 requests per minute to protect the Pterodactyl API budget.

Section sources

Security and Data Exposure Prevention

Enhanced Security Measures

The system implements comprehensive security measures to prevent node-level data exposure in customer responses:

Test Coverage for Security Boundaries

  • Automated Assertions: Tests explicitly verify that the 'nodes' key is never present in customer-facing availability responses
  • Security Validation: Both positive and negative capacity scenarios include assertions to ensure data isolation
  • Mock Testing: Service mocks simulate realistic scenarios while maintaining security boundaries

Security Implementation Details

  • Response Sanitization: Customer endpoints return only aggregate data (max_memory, max_cpu, max_disk, node_count)
  • Admin Isolation: Detailed node information is exclusively available through admin-only endpoints with proper authorization
  • Data Minimization: Even when internal services process node-level data, it is never exposed to customer responses

Security Testing Examples

The test suite includes comprehensive security validation:

  • Verifies absence of 'nodes' key in customer responses
  • Tests both capacity-available and capacity-exhausted scenarios
  • Ensures consistent security behavior across different resource states
flowchart TD
CustomerReq["Customer Request"] --> AuthCheck["Authentication Check"]
AuthCheck --> SecurityLayer["Security Layer"]
SecurityLayer --> DataAggregation["Aggregate Data Only"]
DataAggregation --> SecurityValidation["Security Validation<br/>(No node details)"]
SecurityValidation --> TestCoverage["Automated Test Coverage"]
TestCoverage --> SecureResponse["Secure Response<br/>(Aggregate only)"]
Loading

Diagram sources

Section sources

Dependency Analysis

classDiagram
class AvailabilityController {
+getByLocation(locationId) JsonResponse
+getNodes(locationId) JsonResponse
}
class NodeSelectionService {
+selectBestNode(locationId, requirements) ?array
+getMaxAvailable(locationId) array
}
class ResourceCalculationService {
+getLocationAvailability(locationId, excludeReservationToken) array
+buildClusterSnapshot() array
+verifyAvailability(nodeId, requirements, excludeReservationToken) bool
+testConnection() array
+getLocations() array
}
class AvailabilityApiTest {
+test_has_capacity_false_when_cpu_exhausted_but_memory_positive() void
+test_has_capacity_true_when_all_resources_positive() void
+bindAvailabilityServices(maxAvailable) void
}
AvailabilityController --> NodeSelectionService : "uses"
AvailabilityController --> ResourceCalculationService : "uses"
NodeSelectionService --> ResourceCalculationService : "delegates"
AvailabilityApiTest --> NodeSelectionService : "mocks"
AvailabilityApiTest --> ResourceCalculationService : "mocks"
Loading

Diagram sources

Section sources

Performance Considerations

  • Real-time data fetching:
    • Availability is computed by calling the Pterodactyl API on each request. There is no caching of availability results to avoid staleness and overselling risks.
  • Batched API calls:
    • The service batches node and server queries where possible and paginates large result sets to minimize round-trips while still reflecting current state.
  • Timeouts and retries:
    • Per-attempt timeouts and connect timeouts are set for Pterodactyl API calls. Connection errors trigger retries; non-retryable errors are reported and surfaced as exceptions.
  • Throttling:
    • 30 req/min protects against excessive load on the Pterodactyl API and mitigates abuse.
  • Database reads:
    • Pending reservations are summed per node to adjust available capacity accurately at query time.
  • Enhanced: Security validation adds minimal overhead through automated testing but ensures long-term security posture without runtime performance impact.

Troubleshooting Guide

Common issues and how they manifest:

  • Authentication failure:
    • Missing or invalid session will be rejected by the auth middleware before reaching the controller.
  • Rate limiting:
    • Exceeding 30 requests per minute triggers a throttle response; reduce polling frequency or implement backoff.
  • Invalid location:
    • If the locationId does not resolve to any nodes, the service may return empty aggregates; the controller wraps errors into a consistent failure response.
  • Pterodactyl API errors:
    • Network timeouts, connection failures, or non-2xx responses are caught, reported server-side, and returned as success: false with only the generic availability failure message.
  • Unexpected payload:
    • Malformed or non-JSON responses from Pterodactyl are treated as errors and logged for diagnostics.
  • Enhanced: Security validation failures:
    • If tests detect node-level data exposure, investigate the response structure and ensure proper sanitization in the controller layer.

Verification tips

  • Confirm you are authenticated via a valid session cookie.
  • Ensure your client respects the throttle limits and implements exponential backoff.
  • Validate that the locationId exists in your Pterodactyl instance.
  • Enhanced: Run security tests to verify no node-level data exposure in responses.

Section sources

Conclusion

The GET /api/dynamic-pterodactyl/availability/{locationId} endpoint provides a secure, rate-limited, and real-time view of aggregate capacity for a given location. It exposes only what customers need to make purchasing decisions—maximum allocatable memory, CPU, and disk, along with a simple capacity indicator—while keeping node-level internals private.

Enhanced Security: The system now includes comprehensive automated testing to ensure that node-level data never leaks to customer responses. These security measures provide confidence that the data boundary between customer and admin interfaces remains intact, protecting sensitive infrastructure information while delivering accurate capacity information to customers.

Errors are handled consistently, performance is optimized through batched API calls and careful timeout/retry policies, and security is enforced through both architectural design and comprehensive test coverage.

Clone this wiki locally