Skip to content

Commit

Permalink
feat(backend-api): Add types and queries for DNS records
Browse files Browse the repository at this point in the history
docs(backend-api): Fix cynic web ui link in README
  • Loading branch information
theduke committed Mar 12, 2024
1 parent 6e2ba1e commit a05dfb4
Show file tree
Hide file tree
Showing 6 changed files with 458 additions and 8 deletions.
2 changes: 1 addition & 1 deletion lib/backend-api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,5 @@ This is not always sensible though, depending on which nested data you want to
fetch.

[cynic-api-docs]: https://docs.rs/cynic/latest/cynic/
[cynic-web-ui]: https://docs.rs/cynic/latest/cynic/
[cynic-web-ui]: https://generator.cynic-rs.dev/
[cynic-website]: https://cynic-rs.dev
27 changes: 23 additions & 4 deletions lib/backend-api/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -1511,9 +1511,6 @@ type DNSDomain implements Node {

"""This zone will be accessible at /dns/{slug}/."""
slug: String!
createdAt: DateTime!
updatedAt: DateTime!
deletedAt: DateTime

"""The ID of the object"""
id: ID!
Expand All @@ -1534,12 +1531,17 @@ type ARecord implements Node & DNSRecordInterface {
name: String
ttl: Int
dnsClass: String
domain: DNSDomain!
}

interface DNSRecordInterface {
name: String
ttl: Int
dnsClass: String
domain: DNSDomain!
createdAt: DateTime!
updatedAt: DateTime!
deletedAt: DateTime
}

type AAAARecord implements Node & DNSRecordInterface {
Expand All @@ -1553,6 +1555,7 @@ type AAAARecord implements Node & DNSRecordInterface {
name: String
ttl: Int
dnsClass: String
domain: DNSDomain!
}

type CNAMERecord implements Node & DNSRecordInterface {
Expand All @@ -1568,6 +1571,7 @@ type CNAMERecord implements Node & DNSRecordInterface {
name: String
ttl: Int
dnsClass: String
domain: DNSDomain!
}

type TXTRecord implements Node & DNSRecordInterface {
Expand All @@ -1581,6 +1585,7 @@ type TXTRecord implements Node & DNSRecordInterface {
name: String
ttl: Int
dnsClass: String
domain: DNSDomain!
}

type MXRecord implements Node & DNSRecordInterface {
Expand All @@ -1595,6 +1600,7 @@ type MXRecord implements Node & DNSRecordInterface {
name: String
ttl: Int
dnsClass: String
domain: DNSDomain!
}

type NSRecord implements Node & DNSRecordInterface {
Expand All @@ -1608,6 +1614,7 @@ type NSRecord implements Node & DNSRecordInterface {
name: String
ttl: Int
dnsClass: String
domain: DNSDomain!
}

type CAARecord implements Node & DNSRecordInterface {
Expand All @@ -1623,6 +1630,7 @@ type CAARecord implements Node & DNSRecordInterface {
name: String
ttl: Int
dnsClass: String
domain: DNSDomain!
}

enum DnsmanagerCertificationAuthorityAuthorizationRecordTagChoices {
Expand Down Expand Up @@ -1651,6 +1659,7 @@ type DNAMERecord implements Node & DNSRecordInterface {
name: String
ttl: Int
dnsClass: String
domain: DNSDomain!
}

type PTRRecord implements Node & DNSRecordInterface {
Expand All @@ -1664,6 +1673,7 @@ type PTRRecord implements Node & DNSRecordInterface {
name: String
ttl: Int
dnsClass: String
domain: DNSDomain!
}

type SOARecord implements Node & DNSRecordInterface {
Expand Down Expand Up @@ -1705,6 +1715,7 @@ type SOARecord implements Node & DNSRecordInterface {
name: String
ttl: Int
dnsClass: String
domain: DNSDomain!
}

type SRVRecord implements Node & DNSRecordInterface {
Expand Down Expand Up @@ -1739,6 +1750,7 @@ type SRVRecord implements Node & DNSRecordInterface {
name: String
ttl: Int
dnsClass: String
domain: DNSDomain!
}

type SSHFPRecord implements Node & DNSRecordInterface {
Expand All @@ -1754,6 +1766,7 @@ type SSHFPRecord implements Node & DNSRecordInterface {
name: String
ttl: Int
dnsClass: String
domain: DNSDomain!
}

enum DnsmanagerSshFingerprintRecordAlgorithmChoices {
Expand Down Expand Up @@ -2165,7 +2178,7 @@ type Query {
latestTOS: TermsOfService!
getDeployAppVersion(name: String!, owner: String, version: String): DeployAppVersion
getAllDomains(offset: Int, before: String, after: String, first: Int, last: Int): DNSDomainConnection!
getAllDNSRecords(before: String, after: String, first: Int, last: Int): DNSRecordConnection!
getAllDNSRecords(sortBy: DNSRecordsSortBy, updatedAfter: DateTime, before: String, after: String, first: Int, last: Int): DNSRecordConnection!
getDomain(name: String!): DNSDomain
getDeployApp(name: String!, owner: String): DeployApp
getAppByGlobalAlias(alias: String!): DeployApp
Expand Down Expand Up @@ -2263,6 +2276,11 @@ type DNSRecordEdge {
cursor: String!
}

enum DNSRecordsSortBy {
NEWEST
OLDEST
}

type AppTemplateCategoryConnection {
"""Pagination data for this connection."""
pageInfo: PageInfo!
Expand Down Expand Up @@ -3003,6 +3021,7 @@ input CreateRepoForAppTemplateInput {

type RegisterDomainPayload {
success: Boolean!
domain: DNSDomain
clientMutationId: String
}

Expand Down
66 changes: 66 additions & 0 deletions lib/backend-api/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,72 @@ pub async fn get_app_logs_paginated(
})
}

/// Retrieve a domain by its name.
///
/// Specify with_records to also retrieve all records for the domain.
pub async fn get_domain(
client: &WasmerClient,
domain: String,
) -> Result<Option<types::DnsDomainWithRecords>, anyhow::Error> {
let vars = types::GetDomainVars { domain };

let opt = client
.run_graphql(types::GetDomainWithRecords::build(vars))
.await
.map_err(anyhow::Error::from)?
.get_domain;
Ok(opt)
}

/// Retrieve all DNS records.
///
/// NOTE: this is a privileged operation that requires extra permissions.
pub async fn get_all_dns_records(
client: &WasmerClient,
vars: types::GetAllDnsRecordsVariables,
) -> Result<types::DnsRecordConnection, anyhow::Error> {
client
.run_graphql_strict(types::GetAllDnsRecords::build(vars))
.await
.map_err(anyhow::Error::from)
.map(|x| x.get_all_dnsrecords)
}

/// Retrieve a domain by its name.
///
/// Specify with_records to also retrieve all records for the domain.
pub fn get_all_dns_records_stream(
client: &WasmerClient,
vars: types::GetAllDnsRecordsVariables,
) -> impl futures::Stream<Item = Result<Vec<types::DnsRecord>, anyhow::Error>> + '_ {
futures::stream::try_unfold(
Some(vars),
move |vars: Option<types::GetAllDnsRecordsVariables>| async move {
let vars = match vars {
Some(vars) => vars,
None => return Ok(None),
};

let page = get_all_dns_records(client, vars.clone()).await?;

let end_cursor = page.page_info.end_cursor;

let items = page
.edges
.into_iter()
.filter_map(|x| x.and_then(|x| x.node))
.collect::<Vec<_>>();

let new_vars = end_cursor.map(|c| types::GetAllDnsRecordsVariables {
after: Some(c),
..vars
});

Ok(Some((items, new_vars)))
},
)
}

/// Convert a [`OffsetDateTime`] to a unix timestamp that the WAPM backend
/// understands.
fn unix_timestamp(ts: OffsetDateTime) -> f64 {
Expand Down
Loading

0 comments on commit a05dfb4

Please sign in to comment.