Skip to content

Commit b66d10e

Browse files
authored
[dns-server] reorganize per RFD 619 (#9483)
See [RFD 619](https://rfd.shared.oxide.computer/rfd/619).
1 parent 5af2a32 commit b66d10e

File tree

23 files changed

+450
-445
lines changed

23 files changed

+450
-445
lines changed

Cargo.lock

Lines changed: 16 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ members = [
7171
"internal-dns/cli",
7272
"internal-dns/resolver",
7373
"internal-dns/types",
74+
"internal-dns/types/versions",
7475
"ipcc",
7576
"key-manager",
7677
"live-tests",
@@ -242,6 +243,7 @@ default-members = [
242243
"internal-dns/cli",
243244
"internal-dns/resolver",
244245
"internal-dns/types",
246+
"internal-dns/types/versions",
245247
"ipcc",
246248
"key-manager",
247249
"live-tests",
@@ -539,6 +541,7 @@ installinator-common = { path = "installinator-common" }
539541
installinator-common-versions = { path = "installinator-common/versions" }
540542
internal-dns-resolver = { path = "internal-dns/resolver" }
541543
internal-dns-types = { path = "internal-dns/types" }
544+
internal-dns-types-versions = { path = "internal-dns/types/versions" }
542545
ipcc = { path = "ipcc" }
543546
ipnet = "2.9"
544547
itertools = "0.14.0"

clients/dns-service-client/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ workspace = true
1111
chrono.workspace = true
1212
expectorate.workspace = true
1313
http.workspace = true
14-
internal-dns-types.workspace = true
14+
internal-dns-types-versions.workspace = true
1515
progenitor.workspace = true
1616
reqwest = { workspace = true, features = ["json", "rustls-tls", "stream"] }
1717
schemars.workspace = true

clients/dns-service-client/src/lib.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,19 @@ progenitor::generate_api!(
1818
slog::debug!(log, "client response"; "result" => ?result);
1919
}),
2020
replace = {
21-
DnsConfig = internal_dns_types::config::DnsConfig,
22-
DnsConfigParams = internal_dns_types::config::DnsConfigParams,
23-
DnsConfigZone = internal_dns_types::config::DnsConfigZone,
24-
DnsRecord = internal_dns_types::config::DnsRecord,
25-
Srv = internal_dns_types::config::Srv,
21+
DnsConfig = internal_dns_types_versions::latest::config::DnsConfig,
22+
DnsConfigParams = internal_dns_types_versions::latest::config::DnsConfigParams,
23+
DnsConfigZone = internal_dns_types_versions::latest::config::DnsConfigZone,
24+
DnsRecord = internal_dns_types_versions::latest::config::DnsRecord,
25+
Srv = internal_dns_types_versions::latest::config::Srv,
2626
}
2727
);
2828

29-
pub type DnsError = crate::Error<crate::types::Error>;
29+
pub use internal_dns_types_versions::latest::config::{
30+
ERROR_CODE_BAD_UPDATE_GENERATION, ERROR_CODE_UPDATE_IN_PROGRESS,
31+
};
3032

31-
pub const ERROR_CODE_UPDATE_IN_PROGRESS: &'static str = "UpdateInProgress";
32-
pub const ERROR_CODE_BAD_UPDATE_GENERATION: &'static str =
33-
"BadUpdateGeneration";
34-
pub const ERROR_CODE_INCOMPATIBLE_RECORD: &'static str = "IncompatibleRecord";
33+
pub type DnsError = crate::Error<crate::types::Error>;
3534

3635
/// Returns whether an error from this client should be retried
3736
pub fn is_retryable(error: &DnsError) -> bool {

dns-server-api/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ workspace = true
1111
chrono.workspace = true
1212
dropshot.workspace = true
1313
dropshot-api-manager-types.workspace = true
14-
internal-dns-types.workspace = true
14+
internal-dns-types-versions.workspace = true
1515
omicron-workspace-hack.workspace = true
1616
schemars.workspace = true
1717
semver.workspace = true

dns-server-api/src/lib.rs

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@
9191
9292
use dropshot::{HttpError, HttpResponseOk, RequestContext};
9393
use dropshot_api_manager_types::api_versions;
94+
use internal_dns_types_versions::{
95+
latest::{self, config::ERROR_CODE_INCOMPATIBLE_RECORD},
96+
v1, v2,
97+
};
9498

9599
api_versions!([
96100
// WHEN CHANGING THE API (part 1 of 2):
@@ -127,52 +131,64 @@ pub trait DnsServerApi {
127131
#[endpoint(
128132
method = GET,
129133
path = "/config",
130-
operation_id = "dns_config_get",
131-
versions = VERSION_INITIAL..VERSION_SOA_AND_NS
134+
versions = VERSION_SOA_AND_NS..
132135
)]
133-
async fn dns_config_get_v1(
136+
async fn dns_config_get(
134137
rqctx: RequestContext<Self::Context>,
135-
) -> Result<
136-
HttpResponseOk<internal_dns_types::v1::config::DnsConfig>,
137-
HttpError,
138-
>;
138+
) -> Result<HttpResponseOk<latest::config::DnsConfig>, HttpError>;
139139

140140
#[endpoint(
141141
method = GET,
142142
path = "/config",
143143
operation_id = "dns_config_get",
144-
versions = VERSION_SOA_AND_NS..
144+
versions = VERSION_INITIAL..VERSION_SOA_AND_NS
145145
)]
146-
async fn dns_config_get_v2(
146+
async fn dns_config_get_v1(
147147
rqctx: RequestContext<Self::Context>,
148-
) -> Result<
149-
HttpResponseOk<internal_dns_types::v2::config::DnsConfig>,
150-
HttpError,
151-
>;
148+
) -> Result<HttpResponseOk<v1::config::DnsConfig>, HttpError> {
149+
Self::dns_config_get(rqctx).await?.try_map(|config| {
150+
config.try_into().map_err(
151+
|v2::config::V2ToV1TranslationError::IncompatibleRecord| {
152+
HttpError::for_bad_request(
153+
None,
154+
ERROR_CODE_INCOMPATIBLE_RECORD.to_string(),
155+
)
156+
},
157+
)
158+
})
159+
}
152160

153161
#[endpoint(
154162
method = PUT,
155163
path = "/config",
156-
operation_id = "dns_config_put",
157-
versions = VERSION_INITIAL..VERSION_SOA_AND_NS,
164+
versions = VERSION_SOA_AND_NS..
158165
)]
159-
async fn dns_config_put_v1(
166+
async fn dns_config_put(
160167
rqctx: RequestContext<Self::Context>,
161-
rq: dropshot::TypedBody<
162-
internal_dns_types::v1::config::DnsConfigParams,
163-
>,
168+
rq: dropshot::TypedBody<latest::config::DnsConfigParams>,
164169
) -> Result<dropshot::HttpResponseUpdatedNoContent, dropshot::HttpError>;
165170

166171
#[endpoint(
167172
method = PUT,
168173
path = "/config",
169174
operation_id = "dns_config_put",
170-
versions = VERSION_SOA_AND_NS..
175+
versions = VERSION_INITIAL..VERSION_SOA_AND_NS,
171176
)]
172-
async fn dns_config_put_v2(
177+
async fn dns_config_put_v1(
173178
rqctx: RequestContext<Self::Context>,
174-
rq: dropshot::TypedBody<
175-
internal_dns_types::v2::config::DnsConfigParams,
176-
>,
177-
) -> Result<dropshot::HttpResponseUpdatedNoContent, dropshot::HttpError>;
179+
rq: dropshot::TypedBody<v1::config::DnsConfigParams>,
180+
) -> Result<dropshot::HttpResponseUpdatedNoContent, dropshot::HttpError>
181+
{
182+
let rq = rq.try_map(|params| {
183+
params.try_into().map_err(
184+
|v2::config::V1ToV2TranslationError::GenerationTooLarge| {
185+
HttpError::for_bad_request(
186+
None,
187+
ERROR_CODE_INCOMPATIBLE_RECORD.to_string(),
188+
)
189+
},
190+
)
191+
})?;
192+
Self::dns_config_put(rqctx, rq).await
193+
}
178194
}

dns-server/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ hickory-resolver.workspace = true
2121
hickory-server.workspace = true
2222
http.workspace = true
2323
internal-dns-types.workspace = true
24+
internal-dns-types-versions.workspace = true
2425
omicron-common.workspace = true
2526
oxide-tokio-rt.workspace = true
2627
pretty-hex.workspace = true

dns-server/src/http_server.rs

Lines changed: 9 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,10 @@
66
77
use crate::storage::{self, UpdateError};
88
use dns_server_api::DnsServerApi;
9-
use dns_service_client::{
10-
ERROR_CODE_BAD_UPDATE_GENERATION, ERROR_CODE_INCOMPATIBLE_RECORD,
11-
ERROR_CODE_UPDATE_IN_PROGRESS,
12-
};
139
use dropshot::RequestContext;
14-
use internal_dns_types::{
15-
v1::{self, config::TranslationError as V1TranslationError},
16-
v2::{self, config::TranslationError as V2TranslationError},
10+
use internal_dns_types::config::{
11+
DnsConfig, DnsConfigParams, ERROR_CODE_BAD_UPDATE_GENERATION,
12+
ERROR_CODE_UPDATE_IN_PROGRESS,
1713
};
1814

1915
pub struct Context {
@@ -36,66 +32,9 @@ enum DnsServerApiImpl {}
3632
impl DnsServerApi for DnsServerApiImpl {
3733
type Context = Context;
3834

39-
async fn dns_config_get_v1(
40-
rqctx: RequestContext<Context>,
41-
) -> Result<
42-
dropshot::HttpResponseOk<v1::config::DnsConfig>,
43-
dropshot::HttpError,
44-
> {
45-
let result = Self::dns_config_get(rqctx).await?;
46-
match result.0.try_into() {
47-
Ok(config) => Ok(dropshot::HttpResponseOk(config)),
48-
Err(V2TranslationError::IncompatibleRecord) => {
49-
Err(dropshot::HttpError::for_bad_request(
50-
None,
51-
ERROR_CODE_INCOMPATIBLE_RECORD.to_string(),
52-
))
53-
}
54-
}
55-
}
56-
57-
async fn dns_config_get_v2(
58-
rqctx: RequestContext<Context>,
59-
) -> Result<
60-
dropshot::HttpResponseOk<v2::config::DnsConfig>,
61-
dropshot::HttpError,
62-
> {
63-
Self::dns_config_get(rqctx).await
64-
}
65-
66-
async fn dns_config_put_v1(
67-
rqctx: RequestContext<Context>,
68-
rq: dropshot::TypedBody<v1::config::DnsConfigParams>,
69-
) -> Result<dropshot::HttpResponseUpdatedNoContent, dropshot::HttpError>
70-
{
71-
let provided_config = match rq.into_inner().try_into() {
72-
Ok(config) => config,
73-
Err(V1TranslationError::GenerationTooLarge) => {
74-
return Err(dropshot::HttpError::for_bad_request(
75-
None,
76-
ERROR_CODE_INCOMPATIBLE_RECORD.to_string(),
77-
));
78-
}
79-
};
80-
Self::dns_config_put(rqctx, provided_config).await
81-
}
82-
83-
async fn dns_config_put_v2(
84-
rqctx: RequestContext<Context>,
85-
rq: dropshot::TypedBody<v2::config::DnsConfigParams>,
86-
) -> Result<dropshot::HttpResponseUpdatedNoContent, dropshot::HttpError>
87-
{
88-
Self::dns_config_put(rqctx, rq.into_inner()).await
89-
}
90-
}
91-
92-
impl DnsServerApiImpl {
9335
async fn dns_config_get(
9436
rqctx: RequestContext<Context>,
95-
) -> Result<
96-
dropshot::HttpResponseOk<v2::config::DnsConfig>,
97-
dropshot::HttpError,
98-
> {
37+
) -> Result<dropshot::HttpResponseOk<DnsConfig>, dropshot::HttpError> {
9938
let apictx = rqctx.context();
10039
let config = apictx.store.dns_config().await.map_err(|e| {
10140
dropshot::HttpError::for_internal_error(format!(
@@ -108,11 +47,14 @@ impl DnsServerApiImpl {
10847

10948
async fn dns_config_put(
11049
rqctx: RequestContext<Context>,
111-
params: v2::config::DnsConfigParams,
50+
rq: dropshot::TypedBody<DnsConfigParams>,
11251
) -> Result<dropshot::HttpResponseUpdatedNoContent, dropshot::HttpError>
11352
{
11453
let apictx = rqctx.context();
115-
apictx.store.dns_config_update(&params, &rqctx.request_id).await?;
54+
apictx
55+
.store
56+
.dns_config_update(&rq.into_inner(), &rqctx.request_id)
57+
.await?;
11658
Ok(dropshot::HttpResponseUpdatedNoContent())
11759
}
11860
}

dns-server/tests/cross_version_test.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const TEST_ZONE: &'static str = "oxide.internal";
2323
// well.
2424
mod v1_client {
2525
use anyhow::Context;
26-
use internal_dns_types::v1;
26+
use internal_dns_types_versions::v1;
2727

2828
use std::collections::HashMap;
2929

@@ -116,8 +116,8 @@ mod v1_client {
116116
pub async fn cross_version_works() -> Result<(), anyhow::Error> {
117117
let test_ctx = init_client_server("cross_version_works").await?;
118118

119-
use internal_dns_types::v1::config::DnsRecord as V1DnsRecord;
120-
use internal_dns_types::v2::config::DnsRecord as V2DnsRecord;
119+
use internal_dns_types_versions::v1::config::DnsRecord as V1DnsRecord;
120+
use internal_dns_types_versions::v2::config::DnsRecord as V2DnsRecord;
121121

122122
let ns1_addr = Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0x1);
123123
let ns1_name = format!("ns1.{TEST_ZONE}.");
@@ -163,7 +163,7 @@ pub async fn cross_version_works() -> Result<(), anyhow::Error> {
163163
Err(dns_service_client::Error::ErrorResponse(rv)) => {
164164
assert_eq!(
165165
rv.message,
166-
dns_service_client::ERROR_CODE_INCOMPATIBLE_RECORD
166+
internal_dns_types::config::ERROR_CODE_INCOMPATIBLE_RECORD
167167
);
168168
}
169169
o => {

internal-dns/types/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ workspace = true
99
[dependencies]
1010
anyhow.workspace = true
1111
chrono.workspace = true
12+
internal-dns-types-versions.workspace = true
1213
omicron-common.workspace = true
1314
omicron-workspace-hack.workspace = true
1415
omicron-uuid-kinds.workspace = true

0 commit comments

Comments
 (0)