diff --git a/changelog.d/2421.added.md b/changelog.d/2421.added.md new file mode 100644 index 00000000000..9f6526d46e6 --- /dev/null +++ b/changelog.d/2421.added.md @@ -0,0 +1 @@ +Added experimental, temp feature for supporting hazelcast pings \ No newline at end of file diff --git a/mirrord-schema.json b/mirrord-schema.json index 0decfa61edf..15a6178a819 100644 --- a/mirrord-schema.json +++ b/mirrord-schema.json @@ -31,6 +31,17 @@ "null" ] }, + "experimental": { + "title": "experimental {#root-experimental}", + "anyOf": [ + { + "$ref": "#/definitions/ExperimentalFileConfig" + }, + { + "type": "null" + } + ] + }, "feature": { "title": "feature {#root-feature}", "anyOf": [ @@ -550,6 +561,21 @@ }, "additionalProperties": false }, + "ExperimentalFileConfig": { + "description": "mirrord Experimental features. This shouldn't be used unless someone from MetalBear/mirrord tells you to.", + "type": "object", + "properties": { + "tcp_ping4_mock": { + "title": "experimental {#fexperimental-tcp_ping4_mock}", + "description": "https://github.com/metalbear-co/mirrord/issues/2421#issuecomment-2093200904", + "type": [ + "boolean", + "null" + ] + } + }, + "additionalProperties": false + }, "FeatureFileConfig": { "description": "Controls mirrord features.\n\nSee the [technical reference, Technical Reference](https://mirrord.dev/docs/reference/) to learn more about what each feature does.\n\nThe [`env`](#feature-env), [`fs`](#feature-fs) and [`network`](#feature-network) options have support for a shortened version, that you can see [here](#root-shortened).\n\n```json { \"feature\": { \"env\": { \"include\": \"DATABASE_USER;PUBLIC_ENV\", \"exclude\": \"DATABASE_PASSWORD;SECRET_ENV\", \"override\": { \"DATABASE_CONNECTION\": \"db://localhost:7777/my-db\", \"LOCAL_BEAR\": \"panda\" } }, \"fs\": { \"mode\": \"write\", \"read_write\": \".+\\.json\" , \"read_only\": [ \".+\\.yaml\", \".+important-file\\.txt\" ], \"local\": [ \".+\\.js\", \".+\\.mjs\" ] }, \"network\": { \"incoming\": { \"mode\": \"steal\", \"http_filter\": { \"header_filter\": \"host: api\\..+\" }, \"port_mapping\": [[ 7777, 8888 ]], \"ignore_localhost\": false, \"ignore_ports\": [9999, 10000] }, \"outgoing\": { \"tcp\": true, \"udp\": true, \"filter\": { \"local\": [\"tcp://1.1.1.0/24:1337\", \"1.1.5.0/24\", \"google.com\", \":53\"] }, \"ignore_localhost\": false, \"unix_streams\": \"bear.+\" }, \"dns\": false }, \"copy_target\": false, \"hostname\": true } } ```", "type": "object", diff --git a/mirrord/config/src/experimental.rs b/mirrord/config/src/experimental.rs new file mode 100644 index 00000000000..97445a1a714 --- /dev/null +++ b/mirrord/config/src/experimental.rs @@ -0,0 +1,24 @@ +use mirrord_analytics::CollectAnalytics; +use mirrord_config_derive::MirrordConfig; +use schemars::JsonSchema; + +use crate::config::source::MirrordConfigSource; + +/// mirrord Experimental features. +/// This shouldn't be used unless someone from MetalBear/mirrord tells you to. +#[derive(MirrordConfig, Clone, Debug)] +#[config(map_to = "ExperimentalFileConfig", derive = "JsonSchema")] +#[cfg_attr(test, config(derive = "PartialEq, Eq"))] +pub struct ExperimentalConfig { + /// ## experimental {#fexperimental-tcp_ping4_mock} + /// + /// https://github.com/metalbear-co/mirrord/issues/2421#issuecomment-2093200904 + #[config(default = true)] + pub tcp_ping4_mock: bool, +} + +impl CollectAnalytics for &ExperimentalConfig { + fn collect_analytics(&self, analytics: &mut mirrord_analytics::Analytics) { + analytics.add("tcp_ping4_mock", self.tcp_ping4_mock); + } +} diff --git a/mirrord/config/src/lib.rs b/mirrord/config/src/lib.rs index f3b5ad21c0a..9490089b938 100644 --- a/mirrord/config/src/lib.rs +++ b/mirrord/config/src/lib.rs @@ -9,6 +9,7 @@ //! including if you only made documentation changes. pub mod agent; pub mod config; +pub mod experimental; pub mod feature; pub mod internal_proxy; pub mod target; @@ -17,6 +18,7 @@ pub mod util; use std::path::Path; use config::{ConfigContext, ConfigError, MirrordConfig}; +use experimental::ExperimentalConfig; use mirrord_analytics::CollectAnalytics; use mirrord_config_derive::MirrordConfig; use schemars::JsonSchema; @@ -314,6 +316,10 @@ pub struct LayerConfig { /// If the remote pod sets this env, the mirrord process will still use it. #[config(env = "MIRRORD_PROXY", default = true)] pub use_proxy: bool, + + /// # experimental {#root-experimental} + #[config(nested)] + pub experimental: ExperimentalConfig, } impl LayerConfig { @@ -665,7 +671,7 @@ mod tests { fn full( #[values(ConfigType::Json, ConfigType::Toml, ConfigType::Yaml)] config_type: ConfigType, ) { - use crate::agent::AgentImageFileConfig; + use crate::{agent::AgentImageFileConfig, experimental::ExperimentalFileConfig}; let input = config_type.full(); @@ -740,6 +746,9 @@ mod tests { kube_context: None, internal_proxy: None, use_proxy: None, + experimental: Some(ExperimentalFileConfig { + tcp_ping4_mock: None, + }), }; assert_eq!(config, expect); diff --git a/mirrord/layer/src/setup.rs b/mirrord/layer/src/setup.rs index 0636552f071..31ed194d3b6 100644 --- a/mirrord/layer/src/setup.rs +++ b/mirrord/layer/src/setup.rs @@ -1,6 +1,7 @@ use std::{collections::HashSet, net::SocketAddr}; use mirrord_config::{ + experimental::ExperimentalConfig, feature::{ env::EnvConfig, fs::FsConfig, @@ -93,6 +94,10 @@ impl LayerSetup { &self.config.feature.network.outgoing } + pub fn experimental(&self) -> &ExperimentalConfig { + &self.config.experimental + } + pub fn remote_dns_enabled(&self) -> bool { self.config.feature.network.dns } diff --git a/mirrord/layer/src/socket/ops.rs b/mirrord/layer/src/socket/ops.rs index 2022e9f84b7..90f7cca0127 100644 --- a/mirrord/layer/src/socket/ops.rs +++ b/mirrord/layer/src/socket/ops.rs @@ -545,6 +545,16 @@ pub(super) fn connect( }; if let Some(ip_address) = optional_ip_address { + if crate::setup().experimental().tcp_ping4_mock { + if ip_address.port() == 7 { + let connect_result = ConnectResult { + result: 0, + error: None, + }; + return Detour::Success(connect_result); + } + } + let ip = ip_address.ip(); if ip.is_loopback() || ip.is_unspecified() { if let Some(result) = connect_to_local_address(sockfd, &user_socket_info, ip_address)? {