magnetar-admin 1.0.1

Apache Pulsar admin REST client for Rust.
Documentation

magnetar-admin

Status: stable (1.0.1). Async admin REST client backing magnetarctl across the V2 + V3 surface — policies, schemas, brokers/bookies, subscriptions, and the V3 Functions / IO Sources / IO Sinks / Packages families.

Async Apache Pulsar admin REST client (/admin/v2/...). Backed by reqwest with the rustls-tls feature — no native-tls, no openssl.

Surface

use magnetar_admin::{AdminClient, TenantInfo};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let admin = AdminClient::builder()
        .service_url("http://localhost:8080".parse()?)
        .token(std::env::var("MAGNETAR_TOKEN").unwrap_or_default())
        .build()?;

    let tenants = admin.tenants_list().await?;
    println!("tenants: {tenants:?}");

    admin
        .tenant_create(
            "acme",
            TenantInfo {
                admin_roles: vec!["admin".into()],
                allowed_clusters: vec!["standalone".into()],
            },
        )
        .await?;
    Ok(())
}

The base service URL is whatever the broker exposes (http://localhost:8080, https://broker.example); the client appends /admin/v2/ itself.

Endpoints implemented

Method Endpoint Pulsar (Java) reference
cluster_list GET /admin/v2/clusters pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v2/Clusters.java
tenants_list GET /admin/v2/tenants pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v2/Tenants.java
tenant_create PUT /admin/v2/tenants/{tenant} pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/TenantsBase.java#createTenant
tenant_delete DELETE /admin/v2/tenants/{tenant} pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/TenantsBase.java#deleteTenant
namespaces_list GET /admin/v2/namespaces/{tenant} pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v2/Namespaces.java
namespace_create PUT /admin/v2/namespaces/{tenant}/{namespace} pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v2/Namespaces.java
namespace_delete DELETE /admin/v2/namespaces/{tenant}/{namespace} pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v2/Namespaces.java
topics_list GET /admin/v2/persistent/{tenant}/{namespace} pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v2/PersistentTopics.java
topic_create_partitioned PUT /admin/v2/persistent/{tenant}/{namespace}/{topic}/partitions PersistentTopics.java#createPartitionedTopic
topic_delete DELETE /admin/v2/persistent/{tenant}/{namespace}/{topic}/partitions?force={bool} PersistentTopics.java#deletePartitionedTopic
topic_stats GET /admin/v2/persistent/{tenant}/{namespace}/{topic}/stats PersistentTopics.java#getStats
topic_partitioned_stats GET /admin/v2/persistent/{tenant}/{namespace}/{topic}/partitioned-stats?perPartition=false PersistentTopics.java#getPartitionedStats
topic_partitions_count GET /admin/v2/persistent/{tenant}/{namespace}/{topic}/partitions PersistentTopics.java#getPartitionedMetadata

TopicStats exposes the high-signal counters (msgInCounter, bytesInCounter) and passes publishers / subscriptions through as raw JSON because the Java schema is large and version-dependent.

topic_partitioned_stats reuses the same TopicStats shape (it carries the broker's aggregated top-level counters); the per-partition breakdown is intentionally dropped. Call topic_partitions_count to size a topic and then either dispatch to topic_stats (non-partitioned) or topic_partitioned_stats (partitioned). The magnetarctl CLI's admin topic-stats does this auto-dispatch.

Auth

AdminClient::builder()
    .service_url(url)
    .token("eyJhbGciOi...".into())  // → Authorization: Bearer …
    .build()?;

OAuth2, SASL, and Athenz live in magnetar-auth-* crates; their integration with the admin client lands later.

TLS

reqwest is built with rustls-tls (workspace-level). native-tls, openssl, and openssl-sys are banned by deny.toml.

Tests

cargo test -p magnetar-admin

Tests assert builder semantics, URL prefix handling, and the TenantInfo JSON layout. Wire-level round-trips run in the e2e suite against apachepulsar/pulsar:4.x.