Skip to content

Working by name

dinio_sdk::ops works the way the CLI does: by zone, name, type and data, looking up uuids for you. Functions take the client and a Zone as returned by zones().get.

use dinio_sdk::ops::{self, AddValue, ValueSelector};
let zone = client.zones().get("example.com").await?;
let www = ops::qualify_name("www", &zone.name)?; // "www.example.com"
let added = ops::add_value(&client, &zone, &www, "A", AddValue {
data: "192.0.2.1".into(),
ttl: Some(300),
..Default::default()
})
.await?;
println!("{} (new set: {})", added.value.uuid, added.new_group);
ops::remove_value(&client, &zone, &www, "A", &ValueSelector::Data("192.0.2.1".into())).await?;

The API takes full names. qualify_name turns a zone-file style name into one; relative_name goes back.

qualify_name(name, "example.com") Result
"@" example.com
"www" www.example.com
"www.example.com" www.example.com
"other.org." other.org

ValueSelector::Data(String) finds a value by its data, compared in the API’s canonical form with same_data (2001:DB8::0001 finds 2001:db8::1, mail.example.com finds mail.example.com.). ValueSelector::Id(Uuid) picks it exactly. When nothing matches, the error is Error::NotFound and its message lists the existing values with their uuids.

Function
group_values(values) Groups a flat Vec<RecordValue> from records().list_all into record sets, without a request.
find_group(client, zone, name, type, with_geo_bans) Option<RecordSet>.
find_value(client, zone, name, type, &selector) (RecordSet, RecordValue).
find_value_with_geo_bans(…) The same, with the value’s geo_bans.
add_value(client, zone, name, type, AddValue) Adds a value; creates the set if needed. Returns Added { value, ttl, new_group }.
update_value(client, zone, name, type, &selector, &RecordValuePatch) Changes one value.
remove_value(client, zone, name, type, &selector) Removes one value; returns it.
remove_group(client, &group) Removes every value of a set; returns them. Refuses up front, with Error::InvalidInput, a set with values Dinio keeps for a redirect or certificate issuance.
check_group_removable(&group) The same check on its own, without a request.

AddValue::ttl applies only to a new record set and defaults to DEFAULT_TTL (3600). For an existing set, a different TTL is Error::InvalidInput — change it with records().set_ttl.

Function
find_zone_for_host(client, host) The most specific zone you can access that host is in — for the zone_id of a redirect or a certificate. Error::NotFound if none.
zone_for_host(&zones, host) The same over a slice of zones you already have, without a request.
find_certificate(client, reference) A certificate by uuid, or by a host name it covers.
find_sinkhole_list(client, reference, include_shared) A sinkhole list by uuid or name: your own first, then, with include_shared, other users’ shared lists. Names are compared ignoring case; an ambiguous name is Error::InvalidInput.
match_sinkhole_list(&lists, reference) The same over a slice of lists, without a request.
find_member(client, zone_id, reference) A zone member by user uuid or email (ignoring case) — for the user_id that zone_members().remove takes. Error::NotFound if none.
match_member(&members, reference) The same over a slice of members, without a request.
Function
find_client_identity(client, reference) One of your client identities by uuid, identify value or name. Names are compared ignoring case; an ambiguous name is Error::InvalidInput.
match_client_identity(&identities, reference) The same over a slice you already have, without a request: Ok(None) if nothing matches.
infer_client_identity_type(identify) Some(ClientIdentityType::Ip) for an IP address; None otherwise.
infer_sinkhole_role_type(pattern) Wildcard for *.name, Exact otherwise. A regex is never inferred.
select_sinkhole_roles(&roles, &SinkholeRoleSelector) Rules by pattern or by uuid, out of every rule of one list (from sinkhole_lists().all_roles). There is no “all”: delete the list to empty it, or import with Replace to swap its rules.

Areas resolve through the GeoCatalog Dinio publishes — the same list it checks ban codes against, listed in Geo areas. Read it once with client.geo().catalog().

let catalog = client.geo().catalog().await?;
let hr = catalog.parse_area("HR")?; // GeoArea { level: Country, code: 191 }
Method or function
catalog.parse_area(input) "HR", "HRV", "Croatia", "Europe", "country:191" → GeoArea { level, code }.
catalog.known_areas() Every country, sub-region and region, as KnownArea { level, code, name, alpha2 }.
catalog.name(area) / catalog.describe(area) "Croatia" / a label for people, with the name and code.
GeoBan::area() The area of a ban returned by the API.

A bare number is rejected — region and country codes overlap — so write country:191 or region:150. A code that is not in the catalog is rejected too.

Function
add_geo_bans(client, &value, &areas) Bans each area for a value read with its geo bans; areas already banned are skipped. Returns AddedGeoBans { created, skipped }.
select_geo_bans(&value, &GeoBanSelector) The value’s bans by area, by uuid, or all of them, without a request. Error::NotFound if an area isn’t banned.
remove_geo_bans(client, &value, &bans) Removes those bans.
use dinio_sdk::ops::{self, ValueSelector};
let selector = ValueSelector::Data("192.0.2.1".into());
let (_, value) = ops::find_value_with_geo_bans(&client, &zone, &www, "A", &selector).await?;
let areas = [catalog.parse_area("RU")?, catalog.parse_area("Eastern Asia")?];
let added = ops::add_geo_bans(&client, &value, &areas).await?;
println!("{} created, {} already banned", added.created.len(), added.skipped.len());