mirror of
https://github.com/logos-blockchain/logos-blockchain-testing.git
synced 2026-05-05 09:23:07 +00:00
Polish cfgsync adapter naming for external use
This commit is contained in:
parent
f1e9eef4e0
commit
a751d819ea
@ -11,28 +11,28 @@ use thiserror::Error;
|
|||||||
/// Type-erased cfgsync adapter error used to preserve source context.
|
/// Type-erased cfgsync adapter error used to preserve source context.
|
||||||
pub type DynCfgsyncError = Box<dyn Error + Send + Sync + 'static>;
|
pub type DynCfgsyncError = Box<dyn Error + Send + Sync + 'static>;
|
||||||
|
|
||||||
/// Per-node rendered config output used to build cfgsync bundles.
|
/// Per-node artifact payload served by cfgsync for one registered node.
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct CfgsyncNodeConfig {
|
pub struct NodeArtifacts {
|
||||||
/// Stable node identifier resolved by the adapter.
|
/// Stable node identifier resolved by the adapter.
|
||||||
pub identifier: String,
|
pub identifier: String,
|
||||||
/// Files served to the node after cfgsync registration.
|
/// Files served to the node after cfgsync registration.
|
||||||
pub files: Vec<ArtifactFile>,
|
pub files: Vec<ArtifactFile>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Node artifacts produced by a cfgsync materializer.
|
/// Materialized artifact files for a single registered node.
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct CfgsyncNodeArtifacts {
|
pub struct ArtifactSet {
|
||||||
files: Vec<ArtifactFile>,
|
files: Vec<ArtifactFile>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Immutable view of registrations currently known to cfgsync.
|
/// Immutable view of registrations currently known to cfgsync.
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct RegistrationSnapshot {
|
pub struct RegistrationSet {
|
||||||
registrations: Vec<NodeRegistration>,
|
registrations: Vec<NodeRegistration>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RegistrationSnapshot {
|
impl RegistrationSet {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(registrations: Vec<NodeRegistration>) -> Self {
|
pub fn new(registrations: Vec<NodeRegistration>) -> Self {
|
||||||
Self { registrations }
|
Self { registrations }
|
||||||
@ -61,7 +61,7 @@ impl RegistrationSnapshot {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CfgsyncNodeArtifacts {
|
impl ArtifactSet {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(files: Vec<ArtifactFile>) -> Self {
|
pub fn new(files: Vec<ArtifactFile>) -> Self {
|
||||||
Self { files }
|
Self { files }
|
||||||
@ -78,15 +78,15 @@ impl CfgsyncNodeArtifacts {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Precomputed node configs indexed by stable identifier.
|
/// Artifact payloads indexed by stable node identifier.
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct CfgsyncNodeCatalog {
|
pub struct NodeArtifactsCatalog {
|
||||||
nodes: HashMap<String, CfgsyncNodeConfig>,
|
nodes: HashMap<String, NodeArtifacts>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CfgsyncNodeCatalog {
|
impl NodeArtifactsCatalog {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(nodes: Vec<CfgsyncNodeConfig>) -> Self {
|
pub fn new(nodes: Vec<NodeArtifacts>) -> Self {
|
||||||
let nodes = nodes
|
let nodes = nodes
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|node| (node.identifier.clone(), node))
|
.map(|node| (node.identifier.clone(), node))
|
||||||
@ -96,7 +96,7 @@ impl CfgsyncNodeCatalog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn resolve(&self, identifier: &str) -> Option<&CfgsyncNodeConfig> {
|
pub fn resolve(&self, identifier: &str) -> Option<&NodeArtifacts> {
|
||||||
self.nodes.get(identifier)
|
self.nodes.get(identifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,35 +111,51 @@ impl CfgsyncNodeCatalog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn into_configs(self) -> Vec<CfgsyncNodeConfig> {
|
pub fn into_nodes(self) -> Vec<NodeArtifacts> {
|
||||||
self.nodes.into_values().collect()
|
self.nodes.into_values().collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[must_use]
|
||||||
|
pub fn into_configs(self) -> Vec<NodeArtifacts> {
|
||||||
|
self.into_nodes()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adapter-side node config materialization contract used by cfgsync server.
|
/// Adapter-side materialization contract for a single registered node.
|
||||||
pub trait CfgsyncMaterializer: Send + Sync {
|
pub trait NodeArtifactsMaterializer: Send + Sync {
|
||||||
fn materialize(
|
fn materialize(
|
||||||
&self,
|
&self,
|
||||||
registration: &NodeRegistration,
|
registration: &NodeRegistration,
|
||||||
registrations: &RegistrationSnapshot,
|
registrations: &RegistrationSet,
|
||||||
) -> Result<Option<CfgsyncNodeArtifacts>, DynCfgsyncError>;
|
) -> Result<Option<ArtifactSet>, DynCfgsyncError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adapter contract for materializing a whole registration snapshot into
|
/// Backward-compatible alias for the previous materializer trait name.
|
||||||
|
pub trait CfgsyncMaterializer: NodeArtifactsMaterializer {}
|
||||||
|
|
||||||
|
impl<T> CfgsyncMaterializer for T where T: NodeArtifactsMaterializer + ?Sized {}
|
||||||
|
|
||||||
|
/// Adapter contract for materializing a whole registration set into
|
||||||
/// per-node cfgsync artifacts.
|
/// per-node cfgsync artifacts.
|
||||||
pub trait CfgsyncSnapshotMaterializer: Send + Sync {
|
pub trait RegistrationSetMaterializer: Send + Sync {
|
||||||
fn materialize_snapshot(
|
fn materialize_snapshot(
|
||||||
&self,
|
&self,
|
||||||
registrations: &RegistrationSnapshot,
|
registrations: &RegistrationSet,
|
||||||
) -> Result<Option<CfgsyncNodeCatalog>, DynCfgsyncError>;
|
) -> Result<Option<NodeArtifactsCatalog>, DynCfgsyncError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CfgsyncMaterializer for CfgsyncNodeCatalog {
|
/// Backward-compatible alias for the previous snapshot materializer trait name.
|
||||||
|
pub trait CfgsyncSnapshotMaterializer: RegistrationSetMaterializer {}
|
||||||
|
|
||||||
|
impl<T> CfgsyncSnapshotMaterializer for T where T: RegistrationSetMaterializer + ?Sized {}
|
||||||
|
|
||||||
|
impl NodeArtifactsMaterializer for NodeArtifactsCatalog {
|
||||||
fn materialize(
|
fn materialize(
|
||||||
&self,
|
&self,
|
||||||
registration: &NodeRegistration,
|
registration: &NodeRegistration,
|
||||||
_registrations: &RegistrationSnapshot,
|
_registrations: &RegistrationSet,
|
||||||
) -> Result<Option<CfgsyncNodeArtifacts>, DynCfgsyncError> {
|
) -> Result<Option<ArtifactSet>, DynCfgsyncError> {
|
||||||
let artifacts = self
|
let artifacts = self
|
||||||
.resolve(®istration.identifier)
|
.resolve(®istration.identifier)
|
||||||
.map(build_node_artifacts_from_config);
|
.map(build_node_artifacts_from_config);
|
||||||
@ -148,22 +164,22 @@ impl CfgsyncMaterializer for CfgsyncNodeCatalog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CfgsyncSnapshotMaterializer for CfgsyncNodeCatalog {
|
impl RegistrationSetMaterializer for NodeArtifactsCatalog {
|
||||||
fn materialize_snapshot(
|
fn materialize_snapshot(
|
||||||
&self,
|
&self,
|
||||||
_registrations: &RegistrationSnapshot,
|
_registrations: &RegistrationSet,
|
||||||
) -> Result<Option<CfgsyncNodeCatalog>, DynCfgsyncError> {
|
) -> Result<Option<NodeArtifactsCatalog>, DynCfgsyncError> {
|
||||||
Ok(Some(self.clone()))
|
Ok(Some(self.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Registration-aware provider backed by an adapter materializer.
|
/// Registration-aware provider backed by an adapter materializer.
|
||||||
pub struct MaterializingConfigProvider<M> {
|
pub struct RegistrationConfigProvider<M> {
|
||||||
materializer: M,
|
materializer: M,
|
||||||
registrations: Mutex<HashMap<String, NodeRegistration>>,
|
registrations: Mutex<HashMap<String, NodeRegistration>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M> MaterializingConfigProvider<M> {
|
impl<M> RegistrationConfigProvider<M> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(materializer: M) -> Self {
|
pub fn new(materializer: M) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -181,23 +197,23 @@ impl<M> MaterializingConfigProvider<M> {
|
|||||||
registrations.get(identifier).cloned()
|
registrations.get(identifier).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn registration_snapshot(&self) -> RegistrationSnapshot {
|
fn registration_set(&self) -> RegistrationSet {
|
||||||
let registrations = self
|
let registrations = self
|
||||||
.registrations
|
.registrations
|
||||||
.lock()
|
.lock()
|
||||||
.expect("cfgsync registration store should not be poisoned");
|
.expect("cfgsync registration store should not be poisoned");
|
||||||
|
|
||||||
RegistrationSnapshot::new(registrations.values().cloned().collect())
|
RegistrationSet::new(registrations.values().cloned().collect())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Registration-aware provider backed by a snapshot materializer.
|
/// Registration-aware provider backed by a snapshot materializer.
|
||||||
pub struct SnapshotMaterializingConfigProvider<M> {
|
pub struct SnapshotConfigProvider<M> {
|
||||||
materializer: M,
|
materializer: M,
|
||||||
registrations: Mutex<HashMap<String, NodeRegistration>>,
|
registrations: Mutex<HashMap<String, NodeRegistration>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M> SnapshotMaterializingConfigProvider<M> {
|
impl<M> SnapshotConfigProvider<M> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(materializer: M) -> Self {
|
pub fn new(materializer: M) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -215,19 +231,19 @@ impl<M> SnapshotMaterializingConfigProvider<M> {
|
|||||||
registrations.get(identifier).cloned()
|
registrations.get(identifier).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn registration_snapshot(&self) -> RegistrationSnapshot {
|
fn registration_set(&self) -> RegistrationSet {
|
||||||
let registrations = self
|
let registrations = self
|
||||||
.registrations
|
.registrations
|
||||||
.lock()
|
.lock()
|
||||||
.expect("cfgsync registration store should not be poisoned");
|
.expect("cfgsync registration store should not be poisoned");
|
||||||
|
|
||||||
RegistrationSnapshot::new(registrations.values().cloned().collect())
|
RegistrationSet::new(registrations.values().cloned().collect())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M> ConfigProvider for SnapshotMaterializingConfigProvider<M>
|
impl<M> ConfigProvider for SnapshotConfigProvider<M>
|
||||||
where
|
where
|
||||||
M: CfgsyncSnapshotMaterializer,
|
M: RegistrationSetMaterializer,
|
||||||
{
|
{
|
||||||
fn register(&self, registration: NodeRegistration) -> RegistrationResponse {
|
fn register(&self, registration: NodeRegistration) -> RegistrationResponse {
|
||||||
let mut registrations = self
|
let mut registrations = self
|
||||||
@ -249,7 +265,7 @@ where
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let registrations = self.registration_snapshot();
|
let registrations = self.registration_set();
|
||||||
let catalog = match self.materializer.materialize_snapshot(®istrations) {
|
let catalog = match self.materializer.materialize_snapshot(®istrations) {
|
||||||
Ok(Some(catalog)) => catalog,
|
Ok(Some(catalog)) => catalog,
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
@ -273,9 +289,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M> ConfigProvider for MaterializingConfigProvider<M>
|
impl<M> ConfigProvider for RegistrationConfigProvider<M>
|
||||||
where
|
where
|
||||||
M: CfgsyncMaterializer,
|
M: NodeArtifactsMaterializer,
|
||||||
{
|
{
|
||||||
fn register(&self, registration: NodeRegistration) -> RegistrationResponse {
|
fn register(&self, registration: NodeRegistration) -> RegistrationResponse {
|
||||||
let mut registrations = self
|
let mut registrations = self
|
||||||
@ -296,7 +312,7 @@ where
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let registrations = self.registration_snapshot();
|
let registrations = self.registration_set();
|
||||||
|
|
||||||
match self.materializer.materialize(®istration, ®istrations) {
|
match self.materializer.materialize(®istration, ®istrations) {
|
||||||
Ok(Some(artifacts)) => {
|
Ok(Some(artifacts)) => {
|
||||||
@ -340,6 +356,11 @@ pub trait CfgsyncEnv {
|
|||||||
fn serialize_node_config(config: &Self::NodeConfig) -> Result<String, Self::Error>;
|
fn serialize_node_config(config: &Self::NodeConfig) -> Result<String, Self::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Preferred public name for application-side cfgsync integration.
|
||||||
|
pub trait DeploymentAdapter: CfgsyncEnv {}
|
||||||
|
|
||||||
|
impl<T> DeploymentAdapter for T where T: CfgsyncEnv + ?Sized {}
|
||||||
|
|
||||||
/// High-level failures while building adapter output for cfgsync.
|
/// High-level failures while building adapter output for cfgsync.
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum BuildCfgsyncNodesError {
|
pub enum BuildCfgsyncNodesError {
|
||||||
@ -370,14 +391,14 @@ pub fn build_cfgsync_node_configs<E: CfgsyncEnv>(
|
|||||||
deployment: &E::Deployment,
|
deployment: &E::Deployment,
|
||||||
hostnames: &[String],
|
hostnames: &[String],
|
||||||
) -> Result<Vec<CfgsyncNodeConfig>, BuildCfgsyncNodesError> {
|
) -> Result<Vec<CfgsyncNodeConfig>, BuildCfgsyncNodesError> {
|
||||||
Ok(build_cfgsync_node_catalog::<E>(deployment, hostnames)?.into_configs())
|
Ok(build_node_artifact_catalog::<E>(deployment, hostnames)?.into_nodes())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds cfgsync node configs and indexes them by stable identifier.
|
/// Builds cfgsync node configs and indexes them by stable identifier.
|
||||||
pub fn build_cfgsync_node_catalog<E: CfgsyncEnv>(
|
pub fn build_node_artifact_catalog<E: DeploymentAdapter>(
|
||||||
deployment: &E::Deployment,
|
deployment: &E::Deployment,
|
||||||
hostnames: &[String],
|
hostnames: &[String],
|
||||||
) -> Result<CfgsyncNodeCatalog, BuildCfgsyncNodesError> {
|
) -> Result<NodeArtifactsCatalog, BuildCfgsyncNodesError> {
|
||||||
let nodes = E::nodes(deployment);
|
let nodes = E::nodes(deployment);
|
||||||
ensure_hostname_count(nodes.len(), hostnames.len())?;
|
ensure_hostname_count(nodes.len(), hostnames.len())?;
|
||||||
|
|
||||||
@ -386,7 +407,15 @@ pub fn build_cfgsync_node_catalog<E: CfgsyncEnv>(
|
|||||||
output.push(build_node_entry::<E>(deployment, node, index, hostnames)?);
|
output.push(build_node_entry::<E>(deployment, node, index, hostnames)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(CfgsyncNodeCatalog::new(output))
|
Ok(NodeArtifactsCatalog::new(output))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub fn build_cfgsync_node_catalog<E: CfgsyncEnv>(
|
||||||
|
deployment: &E::Deployment,
|
||||||
|
hostnames: &[String],
|
||||||
|
) -> Result<NodeArtifactsCatalog, BuildCfgsyncNodesError> {
|
||||||
|
build_node_artifact_catalog::<E>(deployment, hostnames)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ensure_hostname_count(nodes: usize, hostnames: usize) -> Result<(), BuildCfgsyncNodesError> {
|
fn ensure_hostname_count(nodes: usize, hostnames: usize) -> Result<(), BuildCfgsyncNodesError> {
|
||||||
@ -397,22 +426,22 @@ fn ensure_hostname_count(nodes: usize, hostnames: usize) -> Result<(), BuildCfgs
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_node_entry<E: CfgsyncEnv>(
|
fn build_node_entry<E: DeploymentAdapter>(
|
||||||
deployment: &E::Deployment,
|
deployment: &E::Deployment,
|
||||||
node: &E::Node,
|
node: &E::Node,
|
||||||
index: usize,
|
index: usize,
|
||||||
hostnames: &[String],
|
hostnames: &[String],
|
||||||
) -> Result<CfgsyncNodeConfig, BuildCfgsyncNodesError> {
|
) -> Result<NodeArtifacts, BuildCfgsyncNodesError> {
|
||||||
let node_config = build_rewritten_node_config::<E>(deployment, node, index, hostnames)?;
|
let node_config = build_rewritten_node_config::<E>(deployment, node, index, hostnames)?;
|
||||||
let config_yaml = E::serialize_node_config(&node_config).map_err(adapter_error)?;
|
let config_yaml = E::serialize_node_config(&node_config).map_err(adapter_error)?;
|
||||||
|
|
||||||
Ok(CfgsyncNodeConfig {
|
Ok(NodeArtifacts {
|
||||||
identifier: E::node_identifier(index, node),
|
identifier: E::node_identifier(index, node),
|
||||||
files: vec![ArtifactFile::new("/config.yaml", &config_yaml)],
|
files: vec![ArtifactFile::new("/config.yaml", &config_yaml)],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_rewritten_node_config<E: CfgsyncEnv>(
|
fn build_rewritten_node_config<E: DeploymentAdapter>(
|
||||||
deployment: &E::Deployment,
|
deployment: &E::Deployment,
|
||||||
node: &E::Node,
|
node: &E::Node,
|
||||||
index: usize,
|
index: usize,
|
||||||
@ -425,10 +454,28 @@ fn build_rewritten_node_config<E: CfgsyncEnv>(
|
|||||||
Ok(node_config)
|
Ok(node_config)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_node_artifacts_from_config(config: &CfgsyncNodeConfig) -> CfgsyncNodeArtifacts {
|
fn build_node_artifacts_from_config(config: &NodeArtifacts) -> ArtifactSet {
|
||||||
CfgsyncNodeArtifacts::new(config.files.clone())
|
ArtifactSet::new(config.files.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub type CfgsyncNodeConfig = NodeArtifacts;
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub type CfgsyncNodeArtifacts = ArtifactSet;
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub type RegistrationSnapshot = RegistrationSet;
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub type CfgsyncNodeCatalog = NodeArtifactsCatalog;
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub type MaterializingConfigProvider<M> = RegistrationConfigProvider<M>;
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub type SnapshotMaterializingConfigProvider<M> = SnapshotConfigProvider<M>;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
@ -437,13 +484,13 @@ mod tests {
|
|||||||
use cfgsync_core::{CfgSyncErrorCode, ConfigProvider, NodeRegistration, RepoResponse};
|
use cfgsync_core::{CfgSyncErrorCode, ConfigProvider, NodeRegistration, RepoResponse};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
CfgsyncMaterializer, CfgsyncNodeArtifacts, CfgsyncNodeCatalog, CfgsyncNodeConfig,
|
ArtifactSet, DynCfgsyncError, NodeArtifacts, NodeArtifactsCatalog,
|
||||||
DynCfgsyncError, MaterializingConfigProvider, RegistrationSnapshot,
|
NodeArtifactsMaterializer, RegistrationConfigProvider, RegistrationSet,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn catalog_resolves_identifier() {
|
fn catalog_resolves_identifier() {
|
||||||
let catalog = CfgsyncNodeCatalog::new(vec![CfgsyncNodeConfig {
|
let catalog = NodeArtifactsCatalog::new(vec![NodeArtifacts {
|
||||||
identifier: "node-1".to_owned(),
|
identifier: "node-1".to_owned(),
|
||||||
files: vec![ArtifactFile::new("/config.yaml", "key: value")],
|
files: vec![ArtifactFile::new("/config.yaml", "key: value")],
|
||||||
}]);
|
}]);
|
||||||
@ -455,11 +502,11 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn materializing_provider_resolves_registered_node() {
|
fn materializing_provider_resolves_registered_node() {
|
||||||
let catalog = CfgsyncNodeCatalog::new(vec![CfgsyncNodeConfig {
|
let catalog = NodeArtifactsCatalog::new(vec![NodeArtifacts {
|
||||||
identifier: "node-1".to_owned(),
|
identifier: "node-1".to_owned(),
|
||||||
files: vec![ArtifactFile::new("/config.yaml", "key: value")],
|
files: vec![ArtifactFile::new("/config.yaml", "key: value")],
|
||||||
}]);
|
}]);
|
||||||
let provider = MaterializingConfigProvider::new(catalog);
|
let provider = RegistrationConfigProvider::new(catalog);
|
||||||
let registration = NodeRegistration::new("node-1", "127.0.0.1".parse().expect("parse ip"));
|
let registration = NodeRegistration::new("node-1", "127.0.0.1".parse().expect("parse ip"));
|
||||||
|
|
||||||
let _ = provider.register(registration.clone());
|
let _ = provider.register(registration.clone());
|
||||||
@ -472,11 +519,11 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn materializing_provider_reports_not_ready_before_registration() {
|
fn materializing_provider_reports_not_ready_before_registration() {
|
||||||
let catalog = CfgsyncNodeCatalog::new(vec![CfgsyncNodeConfig {
|
let catalog = NodeArtifactsCatalog::new(vec![NodeArtifacts {
|
||||||
identifier: "node-1".to_owned(),
|
identifier: "node-1".to_owned(),
|
||||||
files: vec![ArtifactFile::new("/config.yaml", "key: value")],
|
files: vec![ArtifactFile::new("/config.yaml", "key: value")],
|
||||||
}]);
|
}]);
|
||||||
let provider = MaterializingConfigProvider::new(catalog);
|
let provider = RegistrationConfigProvider::new(catalog);
|
||||||
let registration = NodeRegistration::new("node-1", "127.0.0.1".parse().expect("parse ip"));
|
let registration = NodeRegistration::new("node-1", "127.0.0.1".parse().expect("parse ip"));
|
||||||
|
|
||||||
match provider.resolve(®istration) {
|
match provider.resolve(®istration) {
|
||||||
@ -489,12 +536,12 @@ mod tests {
|
|||||||
calls: AtomicUsize,
|
calls: AtomicUsize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CfgsyncMaterializer for ThresholdMaterializer {
|
impl NodeArtifactsMaterializer for ThresholdMaterializer {
|
||||||
fn materialize(
|
fn materialize(
|
||||||
&self,
|
&self,
|
||||||
registration: &NodeRegistration,
|
registration: &NodeRegistration,
|
||||||
registrations: &RegistrationSnapshot,
|
registrations: &RegistrationSet,
|
||||||
) -> Result<Option<CfgsyncNodeArtifacts>, DynCfgsyncError> {
|
) -> Result<Option<ArtifactSet>, DynCfgsyncError> {
|
||||||
self.calls.fetch_add(1, Ordering::SeqCst);
|
self.calls.fetch_add(1, Ordering::SeqCst);
|
||||||
|
|
||||||
if registrations.len() < 2 {
|
if registrations.len() < 2 {
|
||||||
@ -507,13 +554,13 @@ mod tests {
|
|||||||
ArtifactFile::new("/shared.yaml", format!("peers: {peer_count}")),
|
ArtifactFile::new("/shared.yaml", format!("peers: {peer_count}")),
|
||||||
];
|
];
|
||||||
|
|
||||||
Ok(Some(CfgsyncNodeArtifacts::new(files)))
|
Ok(Some(ArtifactSet::new(files)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn materializing_provider_uses_registration_snapshot_for_readiness() {
|
fn materializing_provider_uses_registration_snapshot_for_readiness() {
|
||||||
let provider = MaterializingConfigProvider::new(ThresholdMaterializer {
|
let provider = RegistrationConfigProvider::new(ThresholdMaterializer {
|
||||||
calls: AtomicUsize::new(0),
|
calls: AtomicUsize::new(0),
|
||||||
});
|
});
|
||||||
let node_a = NodeRegistration::new("node-a", "127.0.0.1".parse().expect("parse ip"));
|
let node_a = NodeRegistration::new("node-a", "127.0.0.1".parse().expect("parse ip"));
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use std::{fs, path::Path, sync::Arc};
|
use std::{fs, path::Path, sync::Arc};
|
||||||
|
|
||||||
use anyhow::Context as _;
|
use anyhow::Context as _;
|
||||||
use cfgsync_adapter::{CfgsyncNodeCatalog, MaterializingConfigProvider};
|
use cfgsync_adapter::{NodeArtifacts, NodeArtifactsCatalog, RegistrationConfigProvider};
|
||||||
use cfgsync_core::{CfgSyncBundle, CfgSyncState, ConfigProvider, FileConfigProvider, run_cfgsync};
|
use cfgsync_core::{CfgSyncBundle, CfgSyncState, ConfigProvider, FileConfigProvider, run_cfgsync};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ fn load_bundle_provider(bundle_path: &Path) -> anyhow::Result<Arc<dyn ConfigProv
|
|||||||
fn load_materializing_provider(bundle_path: &Path) -> anyhow::Result<Arc<dyn ConfigProvider>> {
|
fn load_materializing_provider(bundle_path: &Path) -> anyhow::Result<Arc<dyn ConfigProvider>> {
|
||||||
let bundle = load_bundle_yaml(bundle_path)?;
|
let bundle = load_bundle_yaml(bundle_path)?;
|
||||||
let catalog = build_node_catalog(bundle);
|
let catalog = build_node_catalog(bundle);
|
||||||
let provider = MaterializingConfigProvider::new(catalog);
|
let provider = RegistrationConfigProvider::new(catalog);
|
||||||
|
|
||||||
Ok(Arc::new(provider))
|
Ok(Arc::new(provider))
|
||||||
}
|
}
|
||||||
@ -48,17 +48,17 @@ fn load_bundle_yaml(bundle_path: &Path) -> anyhow::Result<CfgSyncBundle> {
|
|||||||
.with_context(|| format!("parsing cfgsync bundle from {}", bundle_path.display()))
|
.with_context(|| format!("parsing cfgsync bundle from {}", bundle_path.display()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_node_catalog(bundle: CfgSyncBundle) -> CfgsyncNodeCatalog {
|
fn build_node_catalog(bundle: CfgSyncBundle) -> NodeArtifactsCatalog {
|
||||||
let nodes = bundle
|
let nodes = bundle
|
||||||
.nodes
|
.nodes
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|node| cfgsync_adapter::CfgsyncNodeConfig {
|
.map(|node| NodeArtifacts {
|
||||||
identifier: node.identifier,
|
identifier: node.identifier,
|
||||||
files: node.files,
|
files: node.files,
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
CfgsyncNodeCatalog::new(nodes)
|
NodeArtifactsCatalog::new(nodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_bundle_path(config_path: &Path, bundle_path: &str) -> std::path::PathBuf {
|
fn resolve_bundle_path(config_path: &Path, bundle_path: &str) -> std::path::PathBuf {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user