feat(backend-api): Add DnsRecord types and queries

This commit is contained in:
Christoph Herzog
2024-03-12 18:54:20 +01:00
parent b17ce9a3cd
commit 707ffa2536
4 changed files with 1026 additions and 119 deletions

View File

@@ -42,5 +42,5 @@ This is not always sensible though, depending on which nested data you want to
fetch. fetch.
[cynic-api-docs]: https://docs.rs/cynic/latest/cynic/ [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 [cynic-website]: https://cynic-rs.dev

View File

@@ -1,3 +1,13 @@
"""
Directs the executor to include this field or fragment only when the user is not logged in.
"""
directive @includeIfLoggedIn on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
"""
Directs the executor to skip this field or fragment when the user is not logged in.
"""
directive @skipIfLoggedIn on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
interface Node { interface Node {
"""The ID of the object""" """The ID of the object"""
id: ID! id: ID!
@@ -47,6 +57,7 @@ type User implements Node & PackageOwner & Owner {
packages(collaborating: Boolean = false, offset: Int, before: String, after: String, first: Int, last: Int): PackageConnection! packages(collaborating: Boolean = false, offset: Int, before: String, after: String, first: Int, last: Int): PackageConnection!
apps(collaborating: Boolean = false, sortBy: DeployAppsSortBy, offset: Int, before: String, after: String, first: Int, last: Int): DeployAppConnection! apps(collaborating: Boolean = false, sortBy: DeployAppsSortBy, offset: Int, before: String, after: String, first: Int, last: Int): DeployAppConnection!
usageMetrics(forRange: MetricRange!, variant: MetricType!): [UsageMetric]! usageMetrics(forRange: MetricRange!, variant: MetricType!): [UsageMetric]!
domains(offset: Int, before: String, after: String, first: Int, last: Int): DNSDomainConnection!
isStaff: Boolean isStaff: Boolean
packageVersions(offset: Int, before: String, after: String, first: Int, last: Int): PackageVersionConnection! packageVersions(offset: Int, before: String, after: String, first: Int, last: Int): PackageVersionConnection!
packageTransfersIncoming(offset: Int, before: String, after: String, first: Int, last: Int): PackageTransferRequestConnection! packageTransfersIncoming(offset: Int, before: String, after: String, first: Int, last: Int): PackageTransferRequestConnection!
@@ -199,6 +210,7 @@ type Namespace implements Node & PackageOwner & Owner {
publicActivity(before: String, after: String, first: Int, last: Int): ActivityEventConnection! publicActivity(before: String, after: String, first: Int, last: Int): ActivityEventConnection!
pendingInvites(offset: Int, before: String, after: String, first: Int, last: Int): NamespaceCollaboratorInviteConnection! pendingInvites(offset: Int, before: String, after: String, first: Int, last: Int): NamespaceCollaboratorInviteConnection!
viewerHasRole(role: GrapheneRole!): Boolean! viewerHasRole(role: GrapheneRole!): Boolean!
viewerAsCollaborator(role: GrapheneRole): NamespaceCollaborator
"""Whether the current user is invited to the namespace""" """Whether the current user is invited to the namespace"""
viewerIsInvited: Boolean! viewerIsInvited: Boolean!
@@ -207,6 +219,7 @@ type Namespace implements Node & PackageOwner & Owner {
viewerInvitation: NamespaceCollaboratorInvite viewerInvitation: NamespaceCollaboratorInvite
packageTransfersIncoming(offset: Int, before: String, after: String, first: Int, last: Int): PackageTransferRequestConnection! packageTransfersIncoming(offset: Int, before: String, after: String, first: Int, last: Int): PackageTransferRequestConnection!
usageMetrics(forRange: MetricRange!, variant: MetricType!): [UsageMetric]! usageMetrics(forRange: MetricRange!, variant: MetricType!): [UsageMetric]!
domains(offset: Int, before: String, after: String, first: Int, last: Int): DNSDomainConnection!
} }
type NamespaceCollaboratorInviteConnection { type NamespaceCollaboratorInviteConnection {
@@ -248,6 +261,9 @@ type NamespaceCollaboratorInvite implements Node {
} }
enum RegistryNamespaceMaintainerInviteRoleChoices { enum RegistryNamespaceMaintainerInviteRoleChoices {
"""Owner"""
OWNER
"""Admin""" """Admin"""
ADMIN ADMIN
@@ -270,6 +286,9 @@ type NamespaceCollaborator implements Node {
} }
enum RegistryNamespaceMaintainerRoleChoices { enum RegistryNamespaceMaintainerRoleChoices {
"""Owner"""
OWNER
"""Admin""" """Admin"""
ADMIN ADMIN
@@ -338,6 +357,8 @@ type Package implements Likeable & Node & PackageOwner {
iconUpdatedAt: DateTime iconUpdatedAt: DateTime
watchersCount: Int! watchersCount: Int!
webcs(offset: Int, before: String, after: String, first: Int, last: Int): WebcImageConnection! webcs(offset: Int, before: String, after: String, first: Int, last: Int): WebcImageConnection!
"""List of app templates for this package"""
appTemplates(offset: Int, before: String, after: String, first: Int, last: Int): AppTemplateConnection! appTemplates(offset: Int, before: String, after: String, first: Int, last: Int): AppTemplateConnection!
packagewebcSet(offset: Int, before: String, after: String, first: Int, last: Int): PackageWebcConnection! packagewebcSet(offset: Int, before: String, after: String, first: Int, last: Int): PackageWebcConnection!
versions: [PackageVersion]! versions: [PackageVersion]!
@@ -366,6 +387,7 @@ type Package implements Likeable & Node & PackageOwner {
collaborators(offset: Int, before: String, after: String, first: Int, last: Int): PackageCollaboratorConnection! collaborators(offset: Int, before: String, after: String, first: Int, last: Int): PackageCollaboratorConnection!
pendingInvites(offset: Int, before: String, after: String, first: Int, last: Int): PackageCollaboratorInviteConnection! pendingInvites(offset: Int, before: String, after: String, first: Int, last: Int): PackageCollaboratorInviteConnection!
viewerHasRole(role: GrapheneRole!): Boolean! viewerHasRole(role: GrapheneRole!): Boolean!
viewerAsCollaborator(role: GrapheneRole): PackageCollaborator
owner: PackageOwner! owner: PackageOwner!
isTransferring: Boolean! isTransferring: Boolean!
activeTransferRequest: PackageTransferRequest activeTransferRequest: PackageTransferRequest
@@ -446,6 +468,7 @@ type PackageVersion implements Node & PackageInstance {
bindings: [PackageVersionLanguageBinding]! bindings: [PackageVersionLanguageBinding]!
npmBindings: PackageVersionNPMBinding npmBindings: PackageVersionNPMBinding
pythonBindings: PackageVersionPythonBinding pythonBindings: PackageVersionPythonBinding
bindingsSet(before: String, after: String, first: Int, last: Int): PackageVersionBindingConnection
hasBindings: Boolean! hasBindings: Boolean!
hasCommands: Boolean! hasCommands: Boolean!
showDeployButton: Boolean! showDeployButton: Boolean!
@@ -599,6 +622,9 @@ type DeployAppVersion implements Node {
"""List of streams to fetch logs from. e.g. stdout, stderr.""" """List of streams to fetch logs from. e.g. stdout, stderr."""
streams: [LogStream] streams: [LogStream]
"""List of instance ids to fetch logs from."""
instanceIds: [String]
before: String before: String
after: String after: String
first: Int first: Int
@@ -608,6 +634,8 @@ type DeployAppVersion implements Node {
sourcePackageVersion: PackageVersion! sourcePackageVersion: PackageVersion!
aggregateMetrics: AggregateMetrics! aggregateMetrics: AggregateMetrics!
volumes: [AppVersionVolume] volumes: [AppVersionVolume]
favicon: URL
screenshot: URL
} }
type DeployApp implements Node & Owner { type DeployApp implements Node & Owner {
@@ -631,6 +659,8 @@ type DeployApp implements Node & Owner {
aliases(offset: Int, before: String, after: String, first: Int, last: Int): AppAliasConnection! aliases(offset: Int, before: String, after: String, first: Int, last: Int): AppAliasConnection!
usageMetrics(forRange: MetricRange!, variant: MetricType!): [UsageMetric]! usageMetrics(forRange: MetricRange!, variant: MetricType!): [UsageMetric]!
deleted: Boolean! deleted: Boolean!
favicon: URL
screenshot: URL
} }
enum DeployAppVersionsSortBy { enum DeployAppVersionsSortBy {
@@ -719,8 +749,15 @@ enum MetricUnit {
enum MetricRange { enum MetricRange {
LAST_24_HOURS LAST_24_HOURS
LAST_30_DAYS LAST_30_DAYS
LAST_1_HOUR
} }
"""
The `URL` scalar type represents a URL as text, represented as UTF-8
character sequences.
"""
scalar URL
type LogConnection { type LogConnection {
"""Pagination data for this connection.""" """Pagination data for this connection."""
pageInfo: PageInfo! pageInfo: PageInfo!
@@ -741,6 +778,7 @@ type LogEdge {
enum LogStream { enum LogStream {
STDOUT STDOUT
STDERR STDERR
RUNTIME
} }
type AppVersionVolume { type AppVersionVolume {
@@ -1052,6 +1090,28 @@ type WEBCFilesystemItem {
offset: Int! offset: Int!
} }
type PackageVersionBindingConnection {
"""Pagination data for this connection."""
pageInfo: PageInfo!
"""Contains the nodes in this connection."""
edges: [PackageVersionBindingEdge]!
"""Total number of items in the connection."""
totalCount: Int
}
"""A Relay edge containing a `PackageVersionBinding` and its cursor."""
type PackageVersionBindingEdge {
"""The item at the end of the edge"""
node: PackageVersionBinding
"""A cursor for use in pagination"""
cursor: String!
}
union PackageVersionBinding = PackageVersionNPMBinding | PackageVersionPythonBinding
type WebcImageConnection { type WebcImageConnection {
"""Pagination data for this connection.""" """Pagination data for this connection."""
pageInfo: PageInfo! pageInfo: PageInfo!
@@ -1256,6 +1316,9 @@ type PackageCollaborator implements Node {
} }
enum RegistryPackageMaintainerRoleChoices { enum RegistryPackageMaintainerRoleChoices {
"""Owner"""
OWNER
"""Admin""" """Admin"""
ADMIN ADMIN
@@ -1283,6 +1346,9 @@ type PackageCollaboratorInvite implements Node {
} }
enum RegistryPackageMaintainerInviteRoleChoices { enum RegistryPackageMaintainerInviteRoleChoices {
"""Owner"""
OWNER
"""Admin""" """Admin"""
ADMIN ADMIN
@@ -1314,6 +1380,7 @@ type PackageCollaboratorInviteEdge {
} }
enum GrapheneRole { enum GrapheneRole {
OWNER
ADMIN ADMIN
EDITOR EDITOR
VIEWER VIEWER
@@ -1419,6 +1486,311 @@ type PackageTransferRequestEdge {
cursor: String! cursor: String!
} }
type DNSDomainConnection {
"""Pagination data for this connection."""
pageInfo: PageInfo!
"""Contains the nodes in this connection."""
edges: [DNSDomainEdge]!
"""Total number of items in the connection."""
totalCount: Int
}
"""A Relay edge containing a `DNSDomain` and its cursor."""
type DNSDomainEdge {
"""The item at the end of the edge"""
node: DNSDomain
"""A cursor for use in pagination"""
cursor: String!
}
type DNSDomain implements Node {
name: String!
"""This zone will be accessible at /dns/{slug}/."""
slug: String!
"""The ID of the object"""
id: ID!
records: [DNSRecord]
owner: Owner!
}
union DNSRecord = ARecord | AAAARecord | CNAMERecord | TXTRecord | MXRecord | NSRecord | CAARecord | DNAMERecord | PTRRecord | SOARecord | SRVRecord | SSHFPRecord
type ARecord implements Node & DNSRecordInterface {
createdAt: DateTime!
updatedAt: DateTime!
deletedAt: DateTime
address: String!
"""The ID of the object"""
id: ID!
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 {
createdAt: DateTime!
updatedAt: DateTime!
deletedAt: DateTime
address: String!
"""The ID of the object"""
id: ID!
name: String
ttl: Int
dnsClass: String
domain: DNSDomain!
}
type CNAMERecord implements Node & DNSRecordInterface {
createdAt: DateTime!
updatedAt: DateTime!
deletedAt: DateTime
"""This domain name will alias to this canonical name."""
cName: String!
"""The ID of the object"""
id: ID!
name: String
ttl: Int
dnsClass: String
domain: DNSDomain!
}
type TXTRecord implements Node & DNSRecordInterface {
createdAt: DateTime!
updatedAt: DateTime!
deletedAt: DateTime
data: String!
"""The ID of the object"""
id: ID!
name: String
ttl: Int
dnsClass: String
domain: DNSDomain!
}
type MXRecord implements Node & DNSRecordInterface {
createdAt: DateTime!
updatedAt: DateTime!
deletedAt: DateTime
preference: Int!
exchange: String!
"""The ID of the object"""
id: ID!
name: String
ttl: Int
dnsClass: String
domain: DNSDomain!
}
type NSRecord implements Node & DNSRecordInterface {
createdAt: DateTime!
updatedAt: DateTime!
deletedAt: DateTime
nsdname: String!
"""The ID of the object"""
id: ID!
name: String
ttl: Int
dnsClass: String
domain: DNSDomain!
}
type CAARecord implements Node & DNSRecordInterface {
createdAt: DateTime!
updatedAt: DateTime!
deletedAt: DateTime
flags: Int!
tag: DnsmanagerCertificationAuthorityAuthorizationRecordTagChoices!
value: String!
"""The ID of the object"""
id: ID!
name: String
ttl: Int
dnsClass: String
domain: DNSDomain!
}
enum DnsmanagerCertificationAuthorityAuthorizationRecordTagChoices {
"""issue"""
ISSUE
"""issue wildcard"""
ISSUEWILD
"""Incident object description exchange format"""
IODEF
}
type DNAMERecord implements Node & DNSRecordInterface {
createdAt: DateTime!
updatedAt: DateTime!
deletedAt: DateTime
"""
This domain name will alias to the entire subtree of that delegation domain.
"""
dName: String!
"""The ID of the object"""
id: ID!
name: String
ttl: Int
dnsClass: String
domain: DNSDomain!
}
type PTRRecord implements Node & DNSRecordInterface {
createdAt: DateTime!
updatedAt: DateTime!
deletedAt: DateTime
ptrdname: String!
"""The ID of the object"""
id: ID!
name: String
ttl: Int
dnsClass: String
domain: DNSDomain!
}
type SOARecord implements Node & DNSRecordInterface {
createdAt: DateTime!
updatedAt: DateTime!
deletedAt: DateTime
"""Primary master name server for this zone."""
mname: String!
"""Email address of the administrator responsible for this zone."""
rname: String!
"""
A slave name server will initiate a zone transfer if this serial is incremented.
"""
serial: BigInt!
"""
Number of seconds after which secondary name servers should query the master to detect zone changes.
"""
refresh: BigInt!
"""
Number of seconds after which secondary name servers should retry to request the serial number from the master if the master does not respond.
"""
retry: BigInt!
"""
Number of seconds after which secondary name servers should stop answering request for this zone if the master does not respond.
"""
expire: BigInt!
"""Time to live for purposes of negative caching."""
minimum: BigInt!
"""The ID of the object"""
id: ID!
name: String
ttl: Int
dnsClass: String
domain: DNSDomain!
}
type SRVRecord implements Node & DNSRecordInterface {
createdAt: DateTime!
updatedAt: DateTime!
deletedAt: DateTime
"""The symbolic name of the desired service."""
service: String!
"""
The transport protocol of the desired service, usually either TCP or UDP.
"""
protocol: String!
"""The priority of the target host, lower value means more preferred."""
priority: Int!
"""
A relative weight for records with the same priority, higher value means higher chance of getting picked.
"""
weight: Int!
port: Int!
"""
The canonical hostname of the machine providing the service, ending in a dot.
"""
target: String!
"""The ID of the object"""
id: ID!
name: String
ttl: Int
dnsClass: String
domain: DNSDomain!
}
type SSHFPRecord implements Node & DNSRecordInterface {
createdAt: DateTime!
updatedAt: DateTime!
deletedAt: DateTime
algorithm: DnsmanagerSshFingerprintRecordAlgorithmChoices!
type: DnsmanagerSshFingerprintRecordTypeChoices!
fingerprint: String!
"""The ID of the object"""
id: ID!
name: String
ttl: Int
dnsClass: String
domain: DNSDomain!
}
enum DnsmanagerSshFingerprintRecordAlgorithmChoices {
"""RSA"""
A_1
"""DSA"""
A_2
"""ECDSA"""
A_3
"""Ed25519"""
A_4
}
enum DnsmanagerSshFingerprintRecordTypeChoices {
"""SHA-1"""
A_1
"""SHA-256"""
A_2
}
type APITokenConnection { type APITokenConnection {
"""Pagination data for this connection.""" """Pagination data for this connection."""
pageInfo: PageInfo! pageInfo: PageInfo!
@@ -1559,6 +1931,121 @@ type Signature {
createdAt: DateTime! createdAt: DateTime!
} }
type StripeCustomer {
id: ID!
}
type Billing {
stripeCustomer: StripeCustomer!
payments: [PaymentIntent]!
paymentMethods: [PaymentMethod]!
}
type PaymentIntent implements Node {
"""The datetime this object was created in stripe."""
created: DateTime
"""Three-letter ISO currency code"""
currency: String!
"""
Status of this PaymentIntent, one of requires_payment_method, requires_confirmation, requires_action, processing, requires_capture, canceled, or succeeded. You can read more about PaymentIntent statuses here.
"""
status: DjstripePaymentIntentStatusChoices!
"""The ID of the object"""
id: ID!
amount: String!
}
enum DjstripePaymentIntentStatusChoices {
"""
Cancellation invalidates the intent for future confirmation and cannot be undone.
"""
CANCELED
"""Required actions have been handled."""
PROCESSING
"""Payment Method require additional action, such as 3D secure."""
REQUIRES_ACTION
"""Capture the funds on the cards which have been put on holds."""
REQUIRES_CAPTURE
"""Intent is ready to be confirmed."""
REQUIRES_CONFIRMATION
"""Intent created and requires a Payment Method to be attached."""
REQUIRES_PAYMENT_METHOD
"""The funds are in your account."""
SUCCEEDED
}
union PaymentMethod = CardPaymentMethod
type CardPaymentMethod implements Node {
"""The ID of the object"""
id: ID!
brand: CardBrand!
country: String!
expMonth: Int!
expYear: Int!
funding: CardFunding!
last4: String!
isDefault: Boolean!
}
"""
Card brand.
Can be amex, diners, discover, jcb, mastercard, unionpay, visa, or unknown.
"""
enum CardBrand {
AMEX
DINERS
DISCOVER
JCB
MASTERCARD
UNIONPAY
VISA
UNKNOWN
}
"""
Card funding type.
Can be credit, debit, prepaid, or unknown.
"""
enum CardFunding {
CREDIT
DEBIT
PREPAID
UNKNOWN
}
type Payment {
id: ID
amount: String
paidOn: DateTime
}
"""Log entry for deploy app."""
type Log {
"""Timestamp in nanoseconds"""
timestamp: Float!
"""ISO 8601 string in UTC"""
datetime: DateTime!
"""Log message"""
message: String!
"""Log stream"""
stream: LogStream
}
type UserNotificationKindIncomingPackageTransfer { type UserNotificationKindIncomingPackageTransfer {
packageTransferRequest: PackageTransferRequest! packageTransferRequest: PackageTransferRequest!
} }
@@ -1687,131 +2174,19 @@ input WorkloadRunnerWasmSourceV1 {
webc: WebcSourceV1! webc: WebcSourceV1!
} }
type StripeCustomer {
id: ID!
}
type Billing {
stripeCustomer: StripeCustomer!
payments: [PaymentIntent]!
paymentMethods: [PaymentMethod]!
}
type PaymentIntent implements Node {
"""The datetime this object was created in stripe."""
created: DateTime
"""Three-letter ISO currency code"""
currency: String!
"""
Status of this PaymentIntent, one of requires_payment_method, requires_confirmation, requires_action, processing, requires_capture, canceled, or succeeded. You can read more about PaymentIntent statuses here.
"""
status: DjstripePaymentIntentStatusChoices!
"""The ID of the object"""
id: ID!
amount: String!
}
enum DjstripePaymentIntentStatusChoices {
"""
Cancellation invalidates the intent for future confirmation and cannot be undone.
"""
CANCELED
"""Required actions have been handled."""
PROCESSING
"""Payment Method require additional action, such as 3D secure."""
REQUIRES_ACTION
"""Capture the funds on the cards which have been put on holds."""
REQUIRES_CAPTURE
"""Intent is ready to be confirmed."""
REQUIRES_CONFIRMATION
"""Intent created and requires a Payment Method to be attached."""
REQUIRES_PAYMENT_METHOD
"""The funds are in your account."""
SUCCEEDED
}
union PaymentMethod = CardPaymentMethod
type CardPaymentMethod implements Node {
"""The ID of the object"""
id: ID!
brand: CardBrand!
country: String!
expMonth: Int!
expYear: Int!
funding: CardFunding!
last4: String!
isDefault: Boolean!
}
"""
Card brand.
Can be amex, diners, discover, jcb, mastercard, unionpay, visa, or unknown.
"""
enum CardBrand {
AMEX
DINERS
DISCOVER
JCB
MASTERCARD
UNIONPAY
VISA
UNKNOWN
}
"""
Card funding type.
Can be credit, debit, prepaid, or unknown.
"""
enum CardFunding {
CREDIT
DEBIT
PREPAID
UNKNOWN
}
type Payment {
id: ID
amount: String
paidOn: DateTime
}
"""Log entry for deploy app."""
type Log {
"""Timestamp in nanoseconds"""
timestamp: Float!
"""ISO 8601 string in UTC"""
datetime: DateTime!
"""Log message"""
message: String!
"""Log stream"""
stream: LogStream
}
type Query { type Query {
latestTOS: TermsOfService! latestTOS: TermsOfService!
getDeployAppVersion(name: String!, owner: String, version: String): DeployAppVersion getDeployAppVersion(name: String!, owner: String, version: String): DeployAppVersion
getAllDomains(offset: Int, before: String, after: String, first: Int, last: Int): DNSDomainConnection!
getAllDNSRecords(sortBy: DNSRecordsSortBy, updatedAfter: DateTime, before: String, after: String, first: Int, last: Int): DNSRecordConnection!
getDomain(name: String!): DNSDomain
getDeployApp(name: String!, owner: String): DeployApp getDeployApp(name: String!, owner: String): DeployApp
getAppByGlobalAlias(alias: String!): DeployApp getAppByGlobalAlias(alias: String!): DeployApp
getDeployApps(sortBy: DeployAppsSortBy, updatedAfter: DateTime, offset: Int, before: String, after: String, first: Int, last: Int): DeployAppConnection! getDeployApps(sortBy: DeployAppsSortBy, updatedAfter: DateTime, offset: Int, before: String, after: String, first: Int, last: Int): DeployAppConnection!
getAppVersions(sortBy: DeployAppVersionsSortBy, updatedAfter: DateTime, offset: Int, before: String, after: String, first: Int, last: Int): DeployAppVersionConnection! getAppVersions(sortBy: DeployAppVersionsSortBy, updatedAfter: DateTime, offset: Int, before: String, after: String, first: Int, last: Int): DeployAppVersionConnection!
getAppTemplates(categorySlug: String, offset: Int, before: String, after: String, first: Int, last: Int): AppTemplateConnection! getAppTemplates(categorySlug: String, offset: Int, before: String, after: String, first: Int, last: Int): AppTemplateConnection
getAppTemplate(slug: String!): AppTemplate! getAppTemplate(slug: String!): AppTemplate
getAppTemplateCategories(offset: Int, before: String, after: String, first: Int, last: Int): AppTemplateCategoryConnection! getAppTemplateCategories(offset: Int, before: String, after: String, first: Int, last: Int): AppTemplateCategoryConnection
viewer: User viewer: User
getUser(username: String!): User getUser(username: String!): User
getPasswordResetToken(token: String!): GetPasswordResetToken getPasswordResetToken(token: String!): GetPasswordResetToken
@@ -1881,6 +2256,31 @@ type TermsOfService implements Node {
viewerHasAccepted: Boolean! viewerHasAccepted: Boolean!
} }
type DNSRecordConnection {
"""Pagination data for this connection."""
pageInfo: PageInfo!
"""Contains the nodes in this connection."""
edges: [DNSRecordEdge]!
"""Total number of items in the connection."""
totalCount: Int
}
"""A Relay edge containing a `DNSRecord` and its cursor."""
type DNSRecordEdge {
"""The item at the end of the edge"""
node: DNSRecord
"""A cursor for use in pagination"""
cursor: String!
}
enum DNSRecordsSortBy {
NEWEST
OLDEST
}
type AppTemplateCategoryConnection { type AppTemplateCategoryConnection {
"""Pagination data for this connection.""" """Pagination data for this connection."""
pageInfo: PageInfo! pageInfo: PageInfo!
@@ -2325,6 +2725,10 @@ type Mutation {
acceptAppTransferRequest(input: AcceptAppTransferRequestInput!): AcceptAppTransferRequestPayload acceptAppTransferRequest(input: AcceptAppTransferRequestInput!): AcceptAppTransferRequestPayload
removeAppTransferRequest(input: RemoveAppTransferRequestInput!): RemoveAppTransferRequestPayload removeAppTransferRequest(input: RemoveAppTransferRequestInput!): RemoveAppTransferRequestPayload
createRepoForAppTemplate(input: CreateRepoForAppTemplateInput!): CreateRepoForAppTemplatePayload createRepoForAppTemplate(input: CreateRepoForAppTemplateInput!): CreateRepoForAppTemplatePayload
registerDomain(input: RegisterDomainInput!): RegisterDomainPayload
upsertDNSRecord(input: UpsertDNSRecordInput!): UpsertDNSRecordPayload
deleteDnsRecord(input: DeleteDNSRecordInput!): DeleteDNSRecordPayload
deleteDomain(input: DeleteDomainInput!): DeleteDomainPayload
tokenAuth(input: ObtainJSONWebTokenInput!): ObtainJSONWebTokenPayload tokenAuth(input: ObtainJSONWebTokenInput!): ObtainJSONWebTokenPayload
generateDeployToken(input: GenerateDeployTokenInput!): GenerateDeployTokenPayload generateDeployToken(input: GenerateDeployTokenInput!): GenerateDeployTokenPayload
verifyAccessToken(token: String): Verify verifyAccessToken(token: String): Verify
@@ -2362,6 +2766,7 @@ type Mutation {
watchPackage(input: WatchPackageInput!): WatchPackagePayload watchPackage(input: WatchPackageInput!): WatchPackagePayload
unwatchPackage(input: UnwatchPackageInput!): UnwatchPackagePayload unwatchPackage(input: UnwatchPackageInput!): UnwatchPackagePayload
archivePackage(input: ArchivePackageInput!): ArchivePackagePayload archivePackage(input: ArchivePackageInput!): ArchivePackagePayload
renamePackage(input: RenamePackageInput!): RenamePackagePayload
changePackageVersionArchivedStatus(input: ChangePackageVersionArchivedStatusInput!): ChangePackageVersionArchivedStatusPayload changePackageVersionArchivedStatus(input: ChangePackageVersionArchivedStatusInput!): ChangePackageVersionArchivedStatusPayload
createNamespace(input: CreateNamespaceInput!): CreateNamespacePayload createNamespace(input: CreateNamespaceInput!): CreateNamespacePayload
updateNamespace(input: UpdateNamespaceInput!): UpdateNamespacePayload updateNamespace(input: UpdateNamespaceInput!): UpdateNamespacePayload
@@ -2614,6 +3019,68 @@ input CreateRepoForAppTemplateInput {
clientMutationId: String clientMutationId: String
} }
type RegisterDomainPayload {
success: Boolean!
domain: DNSDomain
clientMutationId: String
}
input RegisterDomainInput {
name: String!
namespace: String!
clientMutationId: String
}
type UpsertDNSRecordPayload {
success: Boolean!
clientMutationId: String
}
input UpsertDNSRecordInput {
kind: RecordKind!
domainId: String!
name: String!
value: String!
ttl: Int
recordId: String
mx: DNSMXExtraInput
clientMutationId: String
}
enum RecordKind {
A
AAAA
CNAME
MX
NS
TXT
DNAME
}
input DNSMXExtraInput {
preference: Int!
}
type DeleteDNSRecordPayload {
success: Boolean!
clientMutationId: String
}
input DeleteDNSRecordInput {
recordId: ID!
clientMutationId: String
}
type DeleteDomainPayload {
success: Boolean!
clientMutationId: String
}
input DeleteDomainInput {
domainId: ID!
clientMutationId: String
}
type ObtainJSONWebTokenPayload { type ObtainJSONWebTokenPayload {
payload: GenericScalar! payload: GenericScalar!
refreshExpiresIn: Int! refreshExpiresIn: Int!
@@ -3086,6 +3553,17 @@ input ArchivePackageInput {
clientMutationId: String clientMutationId: String
} }
type RenamePackagePayload {
package: Package!
clientMutationId: String
}
input RenamePackageInput {
packageId: ID!
newName: String!
clientMutationId: String
}
type ChangePackageVersionArchivedStatusPayload { type ChangePackageVersionArchivedStatusPayload {
packageVersion: PackageVersion! packageVersion: PackageVersion!
clientMutationId: String clientMutationId: String
@@ -3367,6 +3845,9 @@ type Subscription {
"""Filter logs by stream""" """Filter logs by stream"""
streams: [LogStream] streams: [LogStream]
"""Filter logs by instance ids"""
instanceIds: [String]
"""Search logs for this term""" """Search logs for this term"""
searchTerm: String searchTerm: String
): Log! ): Log!

View File

@@ -816,6 +816,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 /// Convert a [`OffsetDateTime`] to a unix timestamp that the WAPM backend
/// understands. /// understands.
fn unix_timestamp(ts: OffsetDateTime) -> f64 { fn unix_timestamp(ts: OffsetDateTime) -> f64 {

View File

@@ -35,6 +35,7 @@ mod queries {
#[derive(cynic::Enum, Clone, Copy, Debug)] #[derive(cynic::Enum, Clone, Copy, Debug)]
pub enum GrapheneRole { pub enum GrapheneRole {
Owner,
Admin, Admin,
Editor, Editor,
Viewer, Viewer,
@@ -608,6 +609,7 @@ mod queries {
pub enum LogStream { pub enum LogStream {
Stdout, Stdout,
Stderr, Stderr,
Runtime,
} }
#[derive(cynic::QueryVariables, Debug, Clone)] #[derive(cynic::QueryVariables, Debug, Clone)]
@@ -730,6 +732,364 @@ mod queries {
pub version: Option<Node>, pub version: Option<Node>,
} }
#[derive(cynic::QueryFragment, Debug, Clone)]
#[cynic(graphql_type = "TXTRecord")]
pub struct TxtRecord {
pub id: cynic::Id,
pub created_at: DateTime,
pub updated_at: DateTime,
pub deleted_at: Option<DateTime>,
pub name: Option<String>,
pub ttl: Option<i32>,
pub data: String,
pub domain: DnsDomain,
}
#[derive(cynic::QueryFragment, Debug, Clone)]
#[cynic(graphql_type = "SSHFPRecord")]
pub struct SshfpRecord {
pub id: cynic::Id,
pub created_at: DateTime,
pub updated_at: DateTime,
pub deleted_at: Option<DateTime>,
pub name: Option<String>,
pub ttl: Option<i32>,
#[cynic(rename = "type")]
pub type_: DnsmanagerSshFingerprintRecordTypeChoices,
pub algorithm: DnsmanagerSshFingerprintRecordAlgorithmChoices,
pub fingerprint: String,
pub domain: DnsDomain,
}
#[derive(cynic::QueryFragment, Debug, Clone)]
#[cynic(graphql_type = "SRVRecord")]
pub struct SrvRecord {
pub id: cynic::Id,
pub created_at: DateTime,
pub updated_at: DateTime,
pub deleted_at: Option<DateTime>,
pub name: Option<String>,
pub ttl: Option<i32>,
pub service: String,
pub protocol: String,
pub priority: i32,
pub weight: i32,
pub port: i32,
pub target: String,
pub domain: DnsDomain,
}
#[derive(cynic::QueryFragment, Debug, Clone)]
#[cynic(graphql_type = "SOARecord")]
pub struct SoaRecord {
pub id: cynic::Id,
pub created_at: DateTime,
pub updated_at: DateTime,
pub deleted_at: Option<DateTime>,
pub name: Option<String>,
pub ttl: Option<i32>,
pub mname: String,
pub rname: String,
pub serial: BigInt,
pub refresh: BigInt,
pub retry: BigInt,
pub expire: BigInt,
pub minimum: BigInt,
pub domain: DnsDomain,
}
#[derive(cynic::Enum, Debug, Clone, Copy)]
pub enum DNSRecordsSortBy {
Newest,
Oldest,
}
#[derive(cynic::QueryVariables, Debug, Clone)]
pub struct GetAllDnsRecordsVariables {
pub after: Option<String>,
pub updated_after: Option<DateTime>,
pub sort_by: Option<DNSRecordsSortBy>,
pub first: Option<i32>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Query", variables = "GetAllDnsRecordsVariables")]
pub struct GetAllDnsRecords {
#[arguments(
first: $first,
after: $after,
updatedAfter: $updated_after,
sortBy: $sort_by
)]
#[cynic(rename = "getAllDNSRecords")]
pub get_all_dnsrecords: DnsRecordConnection,
}
#[derive(cynic::QueryFragment, Debug, Clone)]
#[cynic(graphql_type = "PTRRecord")]
pub struct PtrRecord {
pub id: cynic::Id,
pub created_at: DateTime,
pub updated_at: DateTime,
pub deleted_at: Option<DateTime>,
pub name: Option<String>,
pub ttl: Option<i32>,
pub ptrdname: String,
pub domain: DnsDomain,
}
#[derive(cynic::QueryFragment, Debug, Clone)]
#[cynic(graphql_type = "NSRecord")]
pub struct NsRecord {
pub id: cynic::Id,
pub created_at: DateTime,
pub updated_at: DateTime,
pub deleted_at: Option<DateTime>,
pub name: Option<String>,
pub ttl: Option<i32>,
pub nsdname: String,
pub domain: DnsDomain,
}
#[derive(cynic::QueryFragment, Debug, Clone)]
#[cynic(graphql_type = "MXRecord")]
pub struct MxRecord {
pub id: cynic::Id,
pub created_at: DateTime,
pub updated_at: DateTime,
pub deleted_at: Option<DateTime>,
pub name: Option<String>,
pub ttl: Option<i32>,
pub preference: i32,
pub exchange: String,
pub domain: DnsDomain,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "DNSRecordConnection")]
pub struct DnsRecordConnection {
pub page_info: PageInfo,
pub edges: Vec<Option<DnsRecordEdge>>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "DNSRecordEdge")]
pub struct DnsRecordEdge {
pub node: Option<DnsRecord>,
}
#[derive(cynic::QueryFragment, Debug, Clone)]
#[cynic(graphql_type = "DNAMERecord")]
pub struct DNameRecord {
pub id: cynic::Id,
pub created_at: DateTime,
pub updated_at: DateTime,
pub deleted_at: Option<DateTime>,
pub name: Option<String>,
pub ttl: Option<i32>,
pub d_name: String,
pub domain: DnsDomain,
}
#[derive(cynic::QueryFragment, Debug, Clone)]
#[cynic(graphql_type = "CNAMERecord")]
pub struct CNameRecord {
pub id: cynic::Id,
pub created_at: DateTime,
pub updated_at: DateTime,
pub deleted_at: Option<DateTime>,
pub name: Option<String>,
pub ttl: Option<i32>,
pub c_name: String,
pub domain: DnsDomain,
}
#[derive(cynic::QueryFragment, Debug, Clone)]
#[cynic(graphql_type = "CAARecord")]
pub struct CaaRecord {
pub id: cynic::Id,
pub created_at: DateTime,
pub updated_at: DateTime,
pub deleted_at: Option<DateTime>,
pub name: Option<String>,
pub ttl: Option<i32>,
pub value: String,
pub flags: i32,
pub tag: DnsmanagerCertificationAuthorityAuthorizationRecordTagChoices,
pub domain: DnsDomain,
}
#[derive(cynic::QueryFragment, Debug, Clone)]
#[cynic(graphql_type = "ARecord")]
pub struct ARecord {
pub id: cynic::Id,
pub created_at: DateTime,
pub updated_at: DateTime,
pub deleted_at: Option<DateTime>,
pub name: Option<String>,
pub ttl: Option<i32>,
pub address: String,
pub domain: DnsDomain,
}
#[derive(cynic::QueryFragment, Debug, Clone)]
#[cynic(graphql_type = "AAAARecord")]
pub struct AaaaRecord {
pub id: cynic::Id,
pub created_at: DateTime,
pub updated_at: DateTime,
pub deleted_at: Option<DateTime>,
pub name: Option<String>,
pub ttl: Option<i32>,
pub address: String,
pub domain: DnsDomain,
}
#[derive(cynic::InlineFragments, Debug, Clone)]
#[cynic(graphql_type = "DNSRecord")]
pub enum DnsRecord {
A(ARecord),
AAAA(AaaaRecord),
CName(CNameRecord),
Txt(TxtRecord),
Mx(MxRecord),
Ns(NsRecord),
CAA(CaaRecord),
DName(DNameRecord),
Ptr(PtrRecord),
Soa(SoaRecord),
Srv(SrvRecord),
Sshfp(SshfpRecord),
#[cynic(fallback)]
Unknown,
}
impl DnsRecord {
pub fn id(&self) -> &str {
match self {
DnsRecord::A(record) => record.id.inner(),
DnsRecord::AAAA(record) => record.id.inner(),
DnsRecord::CName(record) => record.id.inner(),
DnsRecord::Txt(record) => record.id.inner(),
DnsRecord::Mx(record) => record.id.inner(),
DnsRecord::Ns(record) => record.id.inner(),
DnsRecord::CAA(record) => record.id.inner(),
DnsRecord::DName(record) => record.id.inner(),
DnsRecord::Ptr(record) => record.id.inner(),
DnsRecord::Soa(record) => record.id.inner(),
DnsRecord::Srv(record) => record.id.inner(),
DnsRecord::Sshfp(record) => record.id.inner(),
DnsRecord::Unknown => "",
}
}
pub fn domain(&self) -> Option<&DnsDomain> {
match self {
DnsRecord::A(record) => Some(&record.domain),
DnsRecord::AAAA(record) => Some(&record.domain),
DnsRecord::CName(record) => Some(&record.domain),
DnsRecord::Txt(record) => Some(&record.domain),
DnsRecord::Mx(record) => Some(&record.domain),
DnsRecord::Ns(record) => Some(&record.domain),
DnsRecord::CAA(record) => Some(&record.domain),
DnsRecord::DName(record) => Some(&record.domain),
DnsRecord::Ptr(record) => Some(&record.domain),
DnsRecord::Soa(record) => Some(&record.domain),
DnsRecord::Srv(record) => Some(&record.domain),
DnsRecord::Sshfp(record) => Some(&record.domain),
DnsRecord::Unknown => None,
}
}
}
#[derive(cynic::Enum, Clone, Copy, Debug)]
pub enum DnsmanagerCertificationAuthorityAuthorizationRecordTagChoices {
Issue,
Issuewild,
Iodef,
}
impl DnsmanagerCertificationAuthorityAuthorizationRecordTagChoices {
pub fn as_str(self) -> &'static str {
match self {
Self::Issue => "issue",
Self::Issuewild => "issuewild",
Self::Iodef => "iodef",
}
}
}
#[derive(cynic::Enum, Clone, Copy, Debug)]
pub enum DnsmanagerSshFingerprintRecordAlgorithmChoices {
#[cynic(rename = "A_1")]
A1,
#[cynic(rename = "A_2")]
A2,
#[cynic(rename = "A_3")]
A3,
#[cynic(rename = "A_4")]
A4,
}
#[derive(cynic::Enum, Clone, Copy, Debug)]
pub enum DnsmanagerSshFingerprintRecordTypeChoices {
#[cynic(rename = "A_1")]
A1,
#[cynic(rename = "A_2")]
A2,
}
#[derive(cynic::QueryVariables, Debug)]
pub struct GetDomainVars {
pub domain: String,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Query", variables = "GetDomainVars")]
pub struct GetDomain {
#[arguments(name: $domain)]
pub get_domain: Option<DnsDomain>,
}
#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Query", variables = "GetDomainVars")]
pub struct GetDomainWithRecords {
#[arguments(name: $domain)]
pub get_domain: Option<DnsDomainWithRecords>,
}
#[derive(cynic::QueryFragment, Debug, Clone)]
#[cynic(graphql_type = "DNSDomain")]
pub struct DnsDomain {
pub id: cynic::Id,
pub name: String,
pub slug: String,
}
#[derive(cynic::QueryFragment, Debug, Clone)]
#[cynic(graphql_type = "DNSDomain")]
pub struct DnsDomainWithRecords {
pub id: cynic::Id,
pub name: String,
pub slug: String,
pub records: Option<Vec<Option<DnsRecord>>>,
}
#[derive(cynic::Scalar, Debug, Clone)]
pub struct BigInt(pub String);
#[derive(cynic::InlineFragments, Debug)] #[derive(cynic::InlineFragments, Debug)]
pub enum Node { pub enum Node {
DeployApp(Box<DeployApp>), DeployApp(Box<DeployApp>),