Skip to content

Commit

Permalink
[Breaking] Deny unknown fields durning configuration serialization (#603
Browse files Browse the repository at this point in the history
)

* We want to error when we encounter unknown fields durning configuration
serialization by using [deny_unknown_fields](https://serde.rs/container-attrs.html#deny_unknown_fields)
  • Loading branch information
adam-singer committed Jan 16, 2024
1 parent 70e8525 commit 95afd36
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 0 deletions.
20 changes: 20 additions & 0 deletions nativelink-config/src/cas_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ pub enum CompressionAlgorithm {
/// different ports. Then configure the non-cloud clients to use one port
/// and cloud-clients to use another.
#[derive(Deserialize, Debug, Default)]
#[serde(deny_unknown_fields)]
pub struct CompressionConfig {
/// The compression algorithm that the server will use when sending
/// responses to clients. Enabling this will likely save a lot of
Expand All @@ -72,6 +73,7 @@ pub struct CompressionConfig {
}

#[derive(Deserialize, Debug)]
#[serde(deny_unknown_fields)]
pub struct AcStoreConfig {
/// The store name referenced in the `stores` map in the main config.
/// This store name referenced here may be reused multiple times.
Expand All @@ -80,6 +82,7 @@ pub struct AcStoreConfig {
}

#[derive(Deserialize, Debug)]
#[serde(deny_unknown_fields)]
pub struct CasStoreConfig {
/// The store name referenced in the `stores` map in the main config.
/// This store name referenced here may be reused multiple times.
Expand All @@ -88,13 +91,15 @@ pub struct CasStoreConfig {
}

#[derive(Deserialize, Debug, Default)]
#[serde(deny_unknown_fields)]
pub struct CapabilitiesRemoteExecutionConfig {
/// Scheduler used to configure the capabilities of remote execution.
#[serde(deserialize_with = "convert_string_with_shellexpand")]
pub scheduler: SchedulerRefName,
}

#[derive(Deserialize, Debug, Default)]
#[serde(deny_unknown_fields)]
pub struct CapabilitiesConfig {
/// Configuration for remote execution capabilities.
/// If not set the capabilities service will inform the client that remote
Expand All @@ -103,6 +108,7 @@ pub struct CapabilitiesConfig {
}

#[derive(Deserialize, Debug)]
#[serde(deny_unknown_fields)]
pub struct ExecutionConfig {
/// The store name referenced in the `stores` map in the main config.
/// This store name referenced here may be reused multiple times.
Expand All @@ -116,6 +122,7 @@ pub struct ExecutionConfig {
}

#[derive(Deserialize, Debug)]
#[serde(deny_unknown_fields)]
pub struct ByteStreamConfig {
/// Name of the store in the "stores" configuration.
pub cas_stores: HashMap<InstanceName, StoreRefName>,
Expand All @@ -139,13 +146,15 @@ pub struct ByteStreamConfig {
}

#[derive(Deserialize, Debug)]
#[serde(deny_unknown_fields)]
pub struct WorkerApiConfig {
/// The scheduler name referenced in the `schedulers` map in the main config.
#[serde(deserialize_with = "convert_string_with_shellexpand")]
pub scheduler: SchedulerRefName,
}

#[derive(Deserialize, Debug, Default)]
#[serde(deny_unknown_fields)]
pub struct PrometheusConfig {
/// Path to register prometheus metrics. If path is "/metrics", and your
/// domain is "example.com", you can reach the endpoint with:
Expand All @@ -157,6 +166,7 @@ pub struct PrometheusConfig {
}

#[derive(Deserialize, Debug, Default)]
#[serde(deny_unknown_fields)]
pub struct AdminConfig {
/// Path to register the admin API. If path is "/admin", and your
/// domain is "example.com", you can reach the endpoint with:
Expand All @@ -168,6 +178,7 @@ pub struct AdminConfig {
}

#[derive(Deserialize, Debug)]
#[serde(deny_unknown_fields)]
pub struct ServicesConfig {
/// The Content Addressable Storage (CAS) backend config.
/// The key is the instance_name used in the protocol and the
Expand Down Expand Up @@ -213,6 +224,7 @@ pub struct ServicesConfig {
}

#[derive(Deserialize, Debug)]
#[serde(deny_unknown_fields)]
pub struct TlsConfig {
/// Path to the certificate file.
#[serde(deserialize_with = "convert_string_with_shellexpand")]
Expand All @@ -230,6 +242,7 @@ pub struct TlsConfig {
/// Note: All of these default to hyper's default values unless otherwise
/// specified.
#[derive(Deserialize, Debug, Default)]
#[serde(deny_unknown_fields)]
pub struct HttpServerConfig {
/// Interval to send keep-alive pings via HTTP2.
/// Note: This is in seconds.
Expand Down Expand Up @@ -276,6 +289,7 @@ pub enum ListenerConfig {
}

#[derive(Deserialize, Debug)]
#[serde(deny_unknown_fields)]
pub struct HttpListener {
/// Address to listen on. Example: `127.0.0.1:8080` or `:8080` to listen
/// to all IPs.
Expand All @@ -299,6 +313,7 @@ pub struct HttpListener {
}

#[derive(Deserialize, Debug)]
#[serde(deny_unknown_fields)]
pub struct ServerConfig {
/// Name of the server. This is used to help identify the service
/// for telemetry and logs.
Expand Down Expand Up @@ -329,6 +344,7 @@ pub enum WorkerProperty {

/// Generic config for an endpoint and associated configs.
#[derive(Deserialize, Debug, Default)]
#[serde(deny_unknown_fields)]
pub struct EndpointConfig {
/// URI of the endpoint.
#[serde(deserialize_with = "convert_string_with_shellexpand")]
Expand Down Expand Up @@ -389,6 +405,7 @@ pub enum EnvironmentSource {
}

#[derive(Deserialize, Debug, Default)]
#[serde(deny_unknown_fields)]
pub struct UploadActionResultConfig {
/// Underlying AC store that the worker will use to publish execution results
/// into. Objects placed in this store should be reachable from the
Expand Down Expand Up @@ -447,6 +464,7 @@ pub struct UploadActionResultConfig {
}

#[derive(Deserialize, Debug, Default)]
#[serde(deny_unknown_fields)]
pub struct LocalWorkerConfig {
/// Name of the worker. This is give a more friendly name to a worker for logging
/// and metric publishing.
Expand Down Expand Up @@ -544,6 +562,7 @@ pub enum WorkerConfig {
}

#[derive(Deserialize, Debug, Clone, Copy)]
#[serde(deny_unknown_fields)]
pub struct GlobalConfig {
/// Maximum number of open files that can be opened at one time.
/// This value is not strictly enforced, it is a best effort. Some internal libraries
Expand Down Expand Up @@ -594,6 +613,7 @@ pub struct GlobalConfig {
}

#[derive(Deserialize, Debug)]
#[serde(deny_unknown_fields)]
pub struct CasConfig {
/// List of stores available to use in this config.
/// The keys can be used in other configs when needing to reference a store.
Expand Down
5 changes: 5 additions & 0 deletions nativelink-config/src/schedulers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ pub enum WorkerAllocationStrategy {
}

#[derive(Deserialize, Debug, Default)]
#[serde(deny_unknown_fields)]
pub struct SimpleScheduler {
/// A list of supported platform properties mapped to how these properties
/// are used when the scheduler looks for worker nodes capable of running
Expand Down Expand Up @@ -125,6 +126,7 @@ pub struct SimpleScheduler {
/// the main cluster of workers. In general, it's more efficient to point the
/// build at the main scheduler directly though.
#[derive(Deserialize, Debug, Default)]
#[serde(deny_unknown_fields)]
pub struct GrpcScheduler {
/// The upstream scheduler to forward requests to.
#[serde(deserialize_with = "convert_string_with_shellexpand")]
Expand All @@ -135,6 +137,7 @@ pub struct GrpcScheduler {
}

#[derive(Deserialize, Debug)]
#[serde(deny_unknown_fields)]
pub struct CacheLookupScheduler {
/// The reference to the action cache store to use to returned cached
/// actions from rather than running them again.
Expand All @@ -150,6 +153,7 @@ pub struct CacheLookupScheduler {
}

#[derive(Deserialize, Debug, Clone)]
#[serde(deny_unknown_fields)]
pub struct PlatformPropertyAddition {
/// The name of the property to add.
pub name: String,
Expand All @@ -167,6 +171,7 @@ pub enum PropertyModification {
}

#[derive(Deserialize, Debug)]
#[serde(deny_unknown_fields)]
pub struct PropertyModifierScheduler {
/// A list of modifications to perform to incoming actions for the nested
/// scheduler. These are performed in order and blindly, so removing a
Expand Down
17 changes: 17 additions & 0 deletions nativelink-config/src/stores.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ pub enum StoreConfig {

/// Configuration for an individual shard of the store.
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(deny_unknown_fields)]
pub struct ShardConfig {
/// Store to shard the data to.
pub store: StoreConfig,
Expand All @@ -182,12 +183,14 @@ pub struct ShardConfig {
}

#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(deny_unknown_fields)]
pub struct ShardStore {
/// Stores to shard the data to.
pub stores: Vec<ShardConfig>,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(deny_unknown_fields)]
pub struct SizePartitioningStore {
/// Size to partition the data on.
#[serde(deserialize_with = "convert_numeric_with_shellexpand")]
Expand All @@ -201,13 +204,15 @@ pub struct SizePartitioningStore {
}

#[derive(Serialize, Deserialize, Debug, Default, Clone)]
#[serde(deny_unknown_fields)]
pub struct RefStore {
/// Name of the store under the root "stores" config object.
#[serde(deserialize_with = "convert_string_with_shellexpand")]
pub name: String,
}

#[derive(Serialize, Deserialize, Debug, Default, Clone)]
#[serde(deny_unknown_fields)]
pub struct FilesystemStore {
/// Path on the system where to store the actual content. This is where
/// the bulk of the data will be placed.
Expand Down Expand Up @@ -238,6 +243,7 @@ pub struct FilesystemStore {
}

#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(deny_unknown_fields)]
pub struct FastSlowStore {
/// Fast store that will be attempted to be contacted before reaching
/// out to the `slow` store.
Expand All @@ -249,6 +255,7 @@ pub struct FastSlowStore {
}

#[derive(Serialize, Deserialize, Debug, Default, Clone)]
#[serde(deny_unknown_fields)]
pub struct MemoryStore {
/// Policy used to evict items out of the store. Failure to set this
/// value will cause items to never be removed from the store causing
Expand All @@ -257,6 +264,7 @@ pub struct MemoryStore {
}

#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(deny_unknown_fields)]
pub struct DedupStore {
/// Store used to store the index of each dedup slice. This store
/// should generally be fast and small.
Expand Down Expand Up @@ -311,6 +319,7 @@ pub struct DedupStore {
}

#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(deny_unknown_fields)]
pub struct ExistenceCacheStore {
/// The underlying store wrap around. All content will first flow
/// through self before forwarding to backend. In the event there
Expand All @@ -326,6 +335,7 @@ pub struct ExistenceCacheStore {
}

#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(deny_unknown_fields)]
pub struct VerifyStore {
/// The underlying store wrap around. All content will first flow
/// through self before forwarding to backend. In the event there
Expand All @@ -351,6 +361,7 @@ pub struct VerifyStore {
}

#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(deny_unknown_fields)]
pub struct CompletenessCheckingStore {
/// The underlying store that will have it's results validated before sending to client.
pub backend: StoreConfig,
Expand All @@ -361,6 +372,7 @@ pub struct CompletenessCheckingStore {
}

#[derive(Serialize, Deserialize, Debug, Default, PartialEq, Clone, Copy)]
#[serde(deny_unknown_fields)]
pub struct Lz4Config {
/// Size of the blocks to compress.
/// Higher values require more ram, but might yield slightly better
Expand Down Expand Up @@ -396,6 +408,7 @@ pub enum CompressionAlgorithm {
}

#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(deny_unknown_fields)]
pub struct CompressionStore {
/// The underlying store wrap around. All content will first flow
/// through self before forwarding to backend. In the event there
Expand All @@ -413,6 +426,7 @@ pub struct CompressionStore {
/// eviction policy removing any expired entries and/or the oldest entries
/// until the store size becomes smaller than max_bytes.
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
#[serde(deny_unknown_fields)]
pub struct EvictionPolicy {
/// Maximum number of bytes before eviction takes place.
/// Default: 0. Zero means never evict based on size.
Expand All @@ -438,6 +452,7 @@ pub struct EvictionPolicy {
}

#[derive(Serialize, Deserialize, Debug, Default, Clone)]
#[serde(deny_unknown_fields)]
pub struct S3Store {
/// S3 region. Usually us-east-1, us-west-2, af-south-1, exc...
#[serde(default, deserialize_with = "convert_string_with_shellexpand")]
Expand Down Expand Up @@ -477,6 +492,7 @@ pub enum StoreType {
}

#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(deny_unknown_fields)]
pub struct GrpcStore {
/// Instance name for GRPC calls. Proxy calls will have the instance_name changed to this.
#[serde(default, deserialize_with = "convert_string_with_shellexpand")]
Expand Down Expand Up @@ -516,6 +532,7 @@ pub struct GrpcStore {
/// Remember that to get total results is additive, meaning the above results
/// would mean a single request would have a total delay of 9.525s - 15.875s.
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
#[serde(deny_unknown_fields)]
pub struct Retry {
/// Maximum number of retries until retrying stops.
/// Setting this to zero will always attempt 1 time, but not retry.
Expand Down

0 comments on commit 95afd36

Please sign in to comment.