diff --git a/custom-transforms-example/src/redis_get_rewrite.rs b/custom-transforms-example/src/redis_get_rewrite.rs index ff61b2b06..a9b679127 100644 --- a/custom-transforms-example/src/redis_get_rewrite.rs +++ b/custom-transforms-example/src/redis_get_rewrite.rs @@ -6,6 +6,7 @@ use shotover::message::Messages; use shotover::transforms::{Transform, TransformBuilder, TransformConfig, Transforms, Wrapper}; #[derive(Deserialize, Debug, Clone)] +#[serde(deny_unknown_fields)] pub struct RedisGetRewriteConfig { pub result: String, } diff --git a/shotover-proxy/tests/cassandra_int_tests/protect.rs b/shotover-proxy/tests/cassandra_int_tests/protect.rs index 98c423416..cc9f04c86 100644 --- a/shotover-proxy/tests/cassandra_int_tests/protect.rs +++ b/shotover-proxy/tests/cassandra_int_tests/protect.rs @@ -5,6 +5,7 @@ use test_helpers::connection::cassandra::{ }; #[derive(Deserialize)] +#[serde(deny_unknown_fields)] pub struct Protected { _cipher: Vec, _nonce: Nonce, diff --git a/shotover/src/config/chain.rs b/shotover/src/config/chain.rs index ed76e91a8..47c87cc0a 100644 --- a/shotover/src/config/chain.rs +++ b/shotover/src/config/chain.rs @@ -7,6 +7,7 @@ use std::fmt::{self, Debug}; use std::iter; #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct TransformChainConfig( #[serde(rename = "TransformChain", deserialize_with = "vec_transform_config")] pub Vec>, diff --git a/shotover/src/config/mod.rs b/shotover/src/config/mod.rs index 0bcd29679..96bbf8c6d 100644 --- a/shotover/src/config/mod.rs +++ b/shotover/src/config/mod.rs @@ -5,6 +5,7 @@ pub mod chain; pub mod topology; #[derive(Deserialize, Debug, Clone)] +#[serde(deny_unknown_fields)] pub struct Config { pub main_log_level: String, pub observability_interface: String, diff --git a/shotover/src/config/topology.rs b/shotover/src/config/topology.rs index e9123da3a..99d71f3ae 100644 --- a/shotover/src/config/topology.rs +++ b/shotover/src/config/topology.rs @@ -9,6 +9,7 @@ use tokio::sync::watch; use tracing::info; #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct Topology { pub sources: HashMap, pub chain_config: HashMap, diff --git a/shotover/src/message/mod.rs b/shotover/src/message/mod.rs index 93b749f4f..953aa2ce8 100644 --- a/shotover/src/message/mod.rs +++ b/shotover/src/message/mod.rs @@ -426,6 +426,7 @@ pub enum Encodable { } #[derive(PartialEq, Debug, Clone, Deserialize)] +#[serde(deny_unknown_fields)] pub enum QueryType { Read, Write, diff --git a/shotover/src/sources/cassandra.rs b/shotover/src/sources/cassandra.rs index 212c944ef..a5f10a4ed 100644 --- a/shotover/src/sources/cassandra.rs +++ b/shotover/src/sources/cassandra.rs @@ -12,6 +12,7 @@ use tokio::task::JoinHandle; use tracing::{error, info}; #[derive(Deserialize, Debug, Clone)] +#[serde(deny_unknown_fields)] pub struct CassandraConfig { pub listen_addr: String, pub connection_limit: Option, diff --git a/shotover/src/sources/kafka.rs b/shotover/src/sources/kafka.rs index 88f3b65e4..a8ca3fb11 100644 --- a/shotover/src/sources/kafka.rs +++ b/shotover/src/sources/kafka.rs @@ -11,6 +11,7 @@ use tokio::task::JoinHandle; use tracing::{error, info}; #[derive(Deserialize, Debug, Clone)] +#[serde(deny_unknown_fields)] pub struct KafkaConfig { pub listen_addr: String, pub connection_limit: Option, diff --git a/shotover/src/sources/mod.rs b/shotover/src/sources/mod.rs index 0b7f082b4..a2f41b959 100644 --- a/shotover/src/sources/mod.rs +++ b/shotover/src/sources/mod.rs @@ -12,6 +12,7 @@ pub mod kafka; pub mod redis; #[derive(Deserialize, Debug, Clone, Copy)] +#[serde(deny_unknown_fields)] pub enum Transport { Tcp, WebSocket, @@ -35,6 +36,7 @@ impl Source { } #[derive(Deserialize, Debug, Clone)] +#[serde(deny_unknown_fields)] pub enum SourceConfig { Cassandra(CassandraConfig), Redis(RedisConfig), diff --git a/shotover/src/sources/redis.rs b/shotover/src/sources/redis.rs index 505ec3edd..9354b0838 100644 --- a/shotover/src/sources/redis.rs +++ b/shotover/src/sources/redis.rs @@ -11,6 +11,7 @@ use tokio::task::JoinHandle; use tracing::{error, info}; #[derive(Deserialize, Debug, Clone)] +#[serde(deny_unknown_fields)] pub struct RedisConfig { pub listen_addr: String, pub connection_limit: Option, diff --git a/shotover/src/tls.rs b/shotover/src/tls.rs index 05c30d9b4..eeb1af7fe 100644 --- a/shotover/src/tls.rs +++ b/shotover/src/tls.rs @@ -19,6 +19,7 @@ use tokio_rustls::server::TlsStream as TlsStreamServer; use tokio_rustls::{TlsAcceptor as RustlsAcceptor, TlsConnector as RustlsConnector}; #[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(deny_unknown_fields)] pub struct TlsAcceptorConfig { /// Path to the certificate authority in PEM format pub certificate_authority_path: Option, @@ -120,6 +121,7 @@ impl TlsAcceptor { } #[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(deny_unknown_fields)] pub struct TlsConnectorConfig { /// Path to the certificate authority in PEM format pub certificate_authority_path: String, diff --git a/shotover/src/transforms/cassandra/peers_rewrite.rs b/shotover/src/transforms/cassandra/peers_rewrite.rs index e22138426..0ce804585 100644 --- a/shotover/src/transforms/cassandra/peers_rewrite.rs +++ b/shotover/src/transforms/cassandra/peers_rewrite.rs @@ -14,6 +14,7 @@ use cql3_parser::select::SelectElement; use serde::Deserialize; #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct CassandraPeersRewriteConfig { pub port: u16, } diff --git a/shotover/src/transforms/cassandra/sink_cluster/mod.rs b/shotover/src/transforms/cassandra/sink_cluster/mod.rs index 257700e0f..400f1e0c7 100644 --- a/shotover/src/transforms/cassandra/sink_cluster/mod.rs +++ b/shotover/src/transforms/cassandra/sink_cluster/mod.rs @@ -48,6 +48,7 @@ const SYSTEM_KEYSPACES: [IdentifierRef<'static>; 3] = [ ]; #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct CassandraSinkClusterConfig { /// contact points must be within the specified data_center and rack. /// If this is not followed, shotover's invariants will still be upheld but shotover will communicate with a @@ -181,6 +182,7 @@ impl TransformBuilder for CassandraSinkClusterBuilder { } #[derive(Deserialize, Debug, Clone)] +#[serde(deny_unknown_fields)] pub struct ShotoverNode { pub address: SocketAddr, pub data_center: String, diff --git a/shotover/src/transforms/cassandra/sink_single.rs b/shotover/src/transforms/cassandra/sink_single.rs index f0652f179..7c2fdba62 100644 --- a/shotover/src/transforms/cassandra/sink_single.rs +++ b/shotover/src/transforms/cassandra/sink_single.rs @@ -16,6 +16,7 @@ use tokio::sync::{mpsc, oneshot}; use tracing::trace; #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct CassandraSinkSingleConfig { #[serde(rename = "remote_address")] pub address: String, diff --git a/shotover/src/transforms/coalesce.rs b/shotover/src/transforms/coalesce.rs index 700237154..cb57ca153 100644 --- a/shotover/src/transforms/coalesce.rs +++ b/shotover/src/transforms/coalesce.rs @@ -14,6 +14,7 @@ pub struct Coalesce { } #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct CoalesceConfig { pub flush_when_buffered_message_count: Option, pub flush_when_millis_since_last_flush: Option, diff --git a/shotover/src/transforms/debug/force_parse.rs b/shotover/src/transforms/debug/force_parse.rs index d74702f69..4892c7a2f 100644 --- a/shotover/src/transforms/debug/force_parse.rs +++ b/shotover/src/transforms/debug/force_parse.rs @@ -15,6 +15,7 @@ use serde::Deserialize; /// Messages that pass through this transform will be parsed. /// Must be individually enabled at the request or response level. #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct DebugForceParseConfig { pub parse_requests: bool, pub parse_responses: bool, @@ -37,6 +38,7 @@ impl TransformConfig for DebugForceParseConfig { /// Messages that pass through this transform will be parsed and then reencoded. /// Must be individually enabled at the request or response level. #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct DebugForceEncodeConfig { pub encode_requests: bool, pub encode_responses: bool, diff --git a/shotover/src/transforms/debug/log_to_file.rs b/shotover/src/transforms/debug/log_to_file.rs index 43f880d43..bb5117c78 100644 --- a/shotover/src/transforms/debug/log_to_file.rs +++ b/shotover/src/transforms/debug/log_to_file.rs @@ -9,6 +9,7 @@ use std::sync::Arc; use tracing::{error, info}; #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct DebugLogToFileConfig; #[cfg(feature = "alpha-transforms")] diff --git a/shotover/src/transforms/debug/printer.rs b/shotover/src/transforms/debug/printer.rs index e976f90ee..640298536 100644 --- a/shotover/src/transforms/debug/printer.rs +++ b/shotover/src/transforms/debug/printer.rs @@ -6,6 +6,7 @@ use serde::Deserialize; use tracing::info; #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct DebugPrinterConfig; #[typetag::deserialize(name = "DebugPrinter")] diff --git a/shotover/src/transforms/debug/returner.rs b/shotover/src/transforms/debug/returner.rs index be5cfeddd..96398a4f7 100644 --- a/shotover/src/transforms/debug/returner.rs +++ b/shotover/src/transforms/debug/returner.rs @@ -6,6 +6,7 @@ use async_trait::async_trait; use serde::Deserialize; #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct DebugReturnerConfig { #[serde(flatten)] response: Response, @@ -20,6 +21,7 @@ impl TransformConfig for DebugReturnerConfig { } #[derive(Debug, Clone, Deserialize)] +#[serde(deny_unknown_fields)] pub enum Response { #[serde(skip)] Message(Messages), diff --git a/shotover/src/transforms/distributed/tuneable_consistency_scatter.rs b/shotover/src/transforms/distributed/tuneable_consistency_scatter.rs index 64de9dfb6..cc5249c47 100644 --- a/shotover/src/transforms/distributed/tuneable_consistency_scatter.rs +++ b/shotover/src/transforms/distributed/tuneable_consistency_scatter.rs @@ -12,6 +12,7 @@ use std::collections::HashMap; use tracing::{error, warn}; #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct TuneableConsistencyScatterConfig { pub route_map: HashMap, pub write_consistency: i32, diff --git a/shotover/src/transforms/filter.rs b/shotover/src/transforms/filter.rs index f7799f94e..47c5c4aef 100644 --- a/shotover/src/transforms/filter.rs +++ b/shotover/src/transforms/filter.rs @@ -15,6 +15,7 @@ pub struct QueryTypeFilter { } #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct QueryTypeFilterConfig { pub filter: QueryType, } diff --git a/shotover/src/transforms/kafka/sink_cluster.rs b/shotover/src/transforms/kafka/sink_cluster.rs index b8baab612..f7827c6ed 100644 --- a/shotover/src/transforms/kafka/sink_cluster.rs +++ b/shotover/src/transforms/kafka/sink_cluster.rs @@ -29,6 +29,7 @@ use tokio::time::timeout; use uuid::Uuid; #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct KafkaSinkClusterConfig { pub first_contact_points: Vec, pub shotover_nodes: Vec, diff --git a/shotover/src/transforms/kafka/sink_single.rs b/shotover/src/transforms/kafka/sink_single.rs index b0e1120bc..36a61df4e 100644 --- a/shotover/src/transforms/kafka/sink_single.rs +++ b/shotover/src/transforms/kafka/sink_single.rs @@ -15,6 +15,7 @@ use tokio::sync::{mpsc, oneshot}; use tokio::time::timeout; #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct KafkaSinkSingleConfig { #[serde(rename = "remote_address")] pub address: String, diff --git a/shotover/src/transforms/load_balance.rs b/shotover/src/transforms/load_balance.rs index 7fb8c0782..12373ada1 100644 --- a/shotover/src/transforms/load_balance.rs +++ b/shotover/src/transforms/load_balance.rs @@ -10,6 +10,7 @@ use std::sync::Arc; use tokio::sync::Mutex; #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct ConnectionBalanceAndPoolConfig { pub name: String, pub max_connections: usize, diff --git a/shotover/src/transforms/null.rs b/shotover/src/transforms/null.rs index db93a56ab..6a984f41a 100644 --- a/shotover/src/transforms/null.rs +++ b/shotover/src/transforms/null.rs @@ -5,6 +5,7 @@ use async_trait::async_trait; use serde::Deserialize; #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct NullSinkConfig; #[typetag::deserialize(name = "NullSink")] diff --git a/shotover/src/transforms/parallel_map.rs b/shotover/src/transforms/parallel_map.rs index 33aa8e6f9..b73cd56c6 100644 --- a/shotover/src/transforms/parallel_map.rs +++ b/shotover/src/transforms/parallel_map.rs @@ -64,6 +64,7 @@ where } #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct ParallelMapConfig { pub parallelism: u32, pub chain: TransformChainConfig, diff --git a/shotover/src/transforms/protect/key_management.rs b/shotover/src/transforms/protect/key_management.rs index ff66d0959..9a4d63cc2 100644 --- a/shotover/src/transforms/protect/key_management.rs +++ b/shotover/src/transforms/protect/key_management.rs @@ -18,6 +18,7 @@ pub enum KeyManager { } #[derive(Deserialize, Debug, Clone)] +#[serde(deny_unknown_fields)] pub enum KeyManagerConfig { AWSKms { region: String, diff --git a/shotover/src/transforms/protect/local_kek.rs b/shotover/src/transforms/protect/local_kek.rs index 6999c790f..0a8641988 100644 --- a/shotover/src/transforms/protect/local_kek.rs +++ b/shotover/src/transforms/protect/local_kek.rs @@ -13,6 +13,7 @@ pub struct LocalKeyManagement { } #[derive(Clone, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] pub struct DEKStructure { pub nonce: Nonce, pub key: Vec, diff --git a/shotover/src/transforms/protect/mod.rs b/shotover/src/transforms/protect/mod.rs index 3b00584a2..e34ef6450 100644 --- a/shotover/src/transforms/protect/mod.rs +++ b/shotover/src/transforms/protect/mod.rs @@ -21,6 +21,7 @@ mod local_kek; mod pkcs_11; #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct ProtectConfig { pub keyspace_table_columns: HashMap>>, pub key_manager: KeyManagerConfig, diff --git a/shotover/src/transforms/query_counter.rs b/shotover/src/transforms/query_counter.rs index 0617a0ef2..2e9028631 100644 --- a/shotover/src/transforms/query_counter.rs +++ b/shotover/src/transforms/query_counter.rs @@ -14,6 +14,7 @@ pub struct QueryCounter { } #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct QueryCounterConfig { pub name: String, } diff --git a/shotover/src/transforms/redis/cache.rs b/shotover/src/transforms/redis/cache.rs index 5e4a000d6..854b246bb 100644 --- a/shotover/src/transforms/redis/cache.rs +++ b/shotover/src/transforms/redis/cache.rs @@ -49,12 +49,14 @@ enum CacheableState { } #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct TableCacheSchemaConfig { partition_key: Vec, range_key: Vec, } #[derive(Deserialize, Debug, Clone)] +#[serde(deny_unknown_fields)] pub struct TableCacheSchema { partition_key: Vec, range_key: Vec, @@ -74,6 +76,7 @@ impl From<&TableCacheSchemaConfig> for TableCacheSchema { } #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct RedisConfig { pub caching_schema: HashMap, pub chain: TransformChainConfig, diff --git a/shotover/src/transforms/redis/cluster_ports_rewrite.rs b/shotover/src/transforms/redis/cluster_ports_rewrite.rs index e5117ca49..1d3cc0496 100644 --- a/shotover/src/transforms/redis/cluster_ports_rewrite.rs +++ b/shotover/src/transforms/redis/cluster_ports_rewrite.rs @@ -8,6 +8,7 @@ use bytes::{BufMut, Bytes, BytesMut}; use serde::Deserialize; #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct RedisClusterPortsRewriteConfig { pub new_port: u16, } diff --git a/shotover/src/transforms/redis/sink_cluster.rs b/shotover/src/transforms/redis/sink_cluster.rs index 890630075..645d04d7d 100644 --- a/shotover/src/transforms/redis/sink_cluster.rs +++ b/shotover/src/transforms/redis/sink_cluster.rs @@ -37,6 +37,7 @@ const SLOT_SIZE: usize = 16384; type ChannelMap = HashMap>>; #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct RedisSinkClusterConfig { pub first_contact_points: Vec, pub direct_destination: Option, diff --git a/shotover/src/transforms/redis/sink_single.rs b/shotover/src/transforms/redis/sink_single.rs index 4f49814be..ecaaa5743 100644 --- a/shotover/src/transforms/redis/sink_single.rs +++ b/shotover/src/transforms/redis/sink_single.rs @@ -21,6 +21,7 @@ use tokio_util::codec::{FramedRead, FramedWrite}; use tracing::Instrument; #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct RedisSinkSingleConfig { #[serde(rename = "remote_address")] pub address: String, diff --git a/shotover/src/transforms/redis/timestamp_tagging.rs b/shotover/src/transforms/redis/timestamp_tagging.rs index 486b7a1c2..24613d68e 100644 --- a/shotover/src/transforms/redis/timestamp_tagging.rs +++ b/shotover/src/transforms/redis/timestamp_tagging.rs @@ -12,6 +12,7 @@ use std::time::{SystemTime, UNIX_EPOCH}; use tracing::{debug, trace}; #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct RedisTimestampTaggerConfig; #[typetag::deserialize(name = "RedisTimestampTagger")] diff --git a/shotover/src/transforms/tee.rs b/shotover/src/transforms/tee.rs index d972a8e3b..0151872c5 100644 --- a/shotover/src/transforms/tee.rs +++ b/shotover/src/transforms/tee.rs @@ -96,6 +96,7 @@ pub enum ConsistencyBehavior { } #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct TeeConfig { pub behavior: Option, pub timeout_micros: Option, @@ -104,6 +105,7 @@ pub struct TeeConfig { } #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub enum ConsistencyBehaviorConfig { Ignore, FailOnMismatch, diff --git a/shotover/src/transforms/throttling.rs b/shotover/src/transforms/throttling.rs index 3c73d828c..6f88469d9 100644 --- a/shotover/src/transforms/throttling.rs +++ b/shotover/src/transforms/throttling.rs @@ -16,6 +16,7 @@ use std::sync::Arc; use super::Transforms; #[derive(Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct RequestThrottlingConfig { pub max_requests_per_second: NonZeroU32, }