Skip to content

Commit cc96b31

Browse files
authored
move cockroach-admin-client NodeId to cockroach-admin-types (#8865)
Currently, the OpenAPI manager has a circular dependency with cockroach-admin-client and cockroach-admin-api, making it hard to make changes to the API that need to happen before the client is updated. The only dependency is `NodeId`, though, which can be moved to this more central location.
1 parent 8516b40 commit cc96b31

File tree

16 files changed

+114
-106
lines changed

16 files changed

+114
-106
lines changed

Cargo.lock

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

cockroach-admin/types/src/lib.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,97 @@ pub enum DecommissionError {
4242
ParseRow(#[from] csv::Error),
4343
}
4444

45+
/// CockroachDB Node ID
46+
///
47+
/// This field is stored internally as a String to avoid questions
48+
/// about size, signedness, etc - it can be treated as an arbitrary
49+
/// unique identifier.
50+
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize)]
51+
pub struct NodeId(pub String);
52+
53+
impl NodeId {
54+
pub fn new(id: String) -> Self {
55+
Self(id)
56+
}
57+
58+
pub fn as_str(&self) -> &str {
59+
&self.0
60+
}
61+
}
62+
63+
impl std::fmt::Display for NodeId {
64+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65+
write!(f, "{}", self.0)
66+
}
67+
}
68+
69+
impl std::str::FromStr for NodeId {
70+
type Err = std::convert::Infallible;
71+
72+
fn from_str(s: &str) -> Result<Self, Self::Err> {
73+
Ok(Self(s.to_string()))
74+
}
75+
}
76+
77+
// When parsing the underlying NodeId, we force it to be interpreted
78+
// as a String. Without this custom Deserialize implementation, we
79+
// encounter parsing errors when querying endpoints which return the
80+
// NodeId as an integer.
81+
impl<'de> serde::Deserialize<'de> for NodeId {
82+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
83+
where
84+
D: serde::Deserializer<'de>,
85+
{
86+
use serde::de::{Error, Visitor};
87+
use std::fmt;
88+
89+
struct NodeIdVisitor;
90+
91+
impl<'de> Visitor<'de> for NodeIdVisitor {
92+
type Value = NodeId;
93+
94+
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
95+
formatter
96+
.write_str("a string or integer representing a node ID")
97+
}
98+
99+
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
100+
where
101+
E: Error,
102+
{
103+
Ok(NodeId(value.to_string()))
104+
}
105+
106+
fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
107+
where
108+
E: Error,
109+
{
110+
Ok(NodeId(value))
111+
}
112+
113+
fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
114+
where
115+
E: Error,
116+
{
117+
Ok(NodeId(value.to_string()))
118+
}
119+
120+
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
121+
where
122+
E: Error,
123+
{
124+
Ok(NodeId(value.to_string()))
125+
}
126+
}
127+
128+
deserializer.deserialize_any(NodeIdVisitor)
129+
}
130+
}
131+
45132
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)]
46133
#[serde(rename_all = "snake_case")]
47134
pub struct NodeStatus {
135+
// TODO use NodeId
48136
pub node_id: String,
49137
pub address: SocketAddr,
50138
pub sql_address: SocketAddr,

cockroach-metrics/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ license = "MPL-2.0"
88
anyhow.workspace = true
99
chrono.workspace = true
1010
cockroach-admin-client.workspace = true
11+
cockroach-admin-types.workspace = true
1112
futures.workspace = true
1213
parallel-task-set.workspace = true
1314
reqwest.workspace = true

cockroach-metrics/src/lib.rs

Lines changed: 5 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use anyhow::{Context, Result};
1111
use chrono::{DateTime, Utc};
1212
use cockroach_admin_client::Client;
13+
use cockroach_admin_types::NodeId;
1314
use futures::stream::{FuturesUnordered, StreamExt};
1415
use parallel_task_set::ParallelTaskSet;
1516
use serde::{Deserialize, Serialize};
@@ -760,93 +761,6 @@ impl PrometheusMetrics {
760761
}
761762
}
762763

763-
/// CockroachDB Node ID
764-
///
765-
/// This field is stored internally as a String to avoid questions
766-
/// about size, signedness, etc - it can be treated as an arbitrary
767-
/// unique identifier.
768-
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize)]
769-
pub struct NodeId(pub String);
770-
771-
impl NodeId {
772-
pub fn new(id: String) -> Self {
773-
Self(id)
774-
}
775-
776-
pub fn as_str(&self) -> &str {
777-
&self.0
778-
}
779-
}
780-
781-
impl std::fmt::Display for NodeId {
782-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
783-
write!(f, "{}", self.0)
784-
}
785-
}
786-
787-
impl std::str::FromStr for NodeId {
788-
type Err = std::convert::Infallible;
789-
790-
fn from_str(s: &str) -> Result<Self, Self::Err> {
791-
Ok(Self(s.to_string()))
792-
}
793-
}
794-
795-
// When parsing the underlying NodeId, we force it to be interpreted
796-
// as a String. Without this custom Deserialize implementation, we
797-
// encounter parsing errors when querying endpoints which return the
798-
// NodeId as an integer.
799-
impl<'de> serde::Deserialize<'de> for NodeId {
800-
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
801-
where
802-
D: serde::Deserializer<'de>,
803-
{
804-
use serde::de::{Error, Visitor};
805-
use std::fmt;
806-
807-
struct NodeIdVisitor;
808-
809-
impl<'de> Visitor<'de> for NodeIdVisitor {
810-
type Value = NodeId;
811-
812-
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
813-
formatter
814-
.write_str("a string or integer representing a node ID")
815-
}
816-
817-
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
818-
where
819-
E: Error,
820-
{
821-
Ok(NodeId(value.to_string()))
822-
}
823-
824-
fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
825-
where
826-
E: Error,
827-
{
828-
Ok(NodeId(value))
829-
}
830-
831-
fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
832-
where
833-
E: Error,
834-
{
835-
Ok(NodeId(value.to_string()))
836-
}
837-
838-
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
839-
where
840-
E: Error,
841-
{
842-
Ok(NodeId(value.to_string()))
843-
}
844-
}
845-
846-
deserializer.deserialize_any(NodeIdVisitor)
847-
}
848-
}
849-
850764
/// CockroachDB node liveness status
851765
///
852766
/// From CockroachDB's [NodeLivenessStatus protobuf enum](https://github.com/cockroachdb/cockroach/blob/release-21.1/pkg/kv/kvserver/liveness/livenesspb/liveness.proto#L107-L138)
@@ -1281,16 +1195,16 @@ sql_exec_latency_bucket{le="0.01"} 25
12811195
assert!(result.unwrap().metrics.is_empty());
12821196

12831197
// Malformed lines (missing values, extra spaces, etc.)
1284-
let malformed_input = r#"
1198+
let malformed_input = "
12851199
metric_name_no_value
1286-
metric_name_with_space
1200+
metric_name_with_space\x20
12871201
metric_name_multiple spaces here
12881202
= value_no_name
12891203
leading_space_metric 123
1290-
trailing_space_metric 456
1204+
trailing_space_metric 456\x20
12911205
metric{label=value} 789
12921206
metric{malformed=label value} 999
1293-
"#;
1207+
";
12941208
let result = PrometheusMetrics::parse(malformed_input);
12951209
assert!(result.is_ok());
12961210
// Should ignore malformed lines gracefully

dev-tools/ls-apis/tests/api_dependencies.out

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,8 @@ Clickhouse Single-Node Cluster Admin (client: clickhouse-admin-single-client)
1212
consumed by: omicron-nexus (omicron/nexus) via 2 paths
1313

1414
CockroachDB Cluster Admin (client: cockroach-admin-client)
15-
consumed by: omicron-gateway (omicron/gateway) via 1 path
1615
consumed by: omicron-nexus (omicron/nexus) via 3 paths
17-
consumed by: omicron-sled-agent (omicron/sled-agent) via 2 paths
18-
consumed by: oximeter-collector (omicron/oximeter/collector) via 1 path
16+
consumed by: omicron-sled-agent (omicron/sled-agent) via 1 path
1917

2018
Crucible Agent (client: crucible-agent-client)
2119
consumed by: omicron-nexus (omicron/nexus) via 1 path

nexus/db-model/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ anyhow.workspace = true
1515
camino.workspace = true
1616
chrono.workspace = true
1717
clickhouse-admin-types.workspace = true
18+
cockroach-admin-types.workspace = true
1819
derive-where.workspace = true
1920
diesel = { workspace = true, features = ["postgres", "r2d2", "chrono", "serde_json", "network-address", "uuid"] }
2021
hex.workspace = true

nexus/db-model/src/inventory.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2918,7 +2918,7 @@ pub struct InvCockroachStatus {
29182918
impl InvCockroachStatus {
29192919
pub fn new(
29202920
inv_collection_id: CollectionUuid,
2921-
node_id: omicron_cockroach_metrics::NodeId,
2921+
node_id: cockroach_admin_types::NodeId,
29222922
status: &CockroachStatus,
29232923
) -> Result<Self, anyhow::Error> {
29242924
Ok(Self {

nexus/db-queries/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ async-trait.workspace = true
1717
camino.workspace = true
1818
chrono.workspace = true
1919
clickhouse-admin-types.workspace = true
20+
cockroach-admin-types.workspace = true
2021
const_format.workspace = true
2122
diesel.workspace = true
2223
diesel-dtrace.workspace = true

nexus/db-queries/src/db/datastore/inventory.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use async_bb8_diesel::AsyncConnection;
1212
use async_bb8_diesel::AsyncRunQueryDsl;
1313
use async_bb8_diesel::AsyncSimpleConnection;
1414
use clickhouse_admin_types::ClickhouseKeeperClusterMembership;
15+
use cockroach_admin_types::NodeId as CockroachNodeId;
1516
use diesel::BoolExpressionMethods;
1617
use diesel::ExpressionMethods;
1718
use diesel::IntoSql;
@@ -102,7 +103,6 @@ use nexus_types::inventory::InternalDnsGenerationStatus;
102103
use nexus_types::inventory::PhysicalDiskFirmware;
103104
use nexus_types::inventory::SledAgent;
104105
use nexus_types::inventory::TimeSync;
105-
use omicron_cockroach_metrics::NodeId as CockroachNodeId;
106106
use omicron_common::api::external::Error;
107107
use omicron_common::api::external::InternalContext;
108108
use omicron_common::api::external::LookupType;

nexus/inventory/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ clickhouse-admin-keeper-client.workspace = true
1616
dns-service-client.workspace = true
1717
clickhouse-admin-server-client.workspace = true
1818
clickhouse-admin-types.workspace = true
19+
cockroach-admin-types.workspace = true
1920
futures.workspace = true
2021
gateway-client.workspace = true
2122
gateway-messages.workspace = true

0 commit comments

Comments
 (0)